Sign in Join
Wiki copytemporary

Lazarus Database Tutorial/ru: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Обзор
22
33Это руководство по работе с различными базами данных в Lazarus. Lazarus поддерживает множество баз данных с помощью внешних пакетов, разработчик должен установить соответствующий пакет для каждой из них. Вы можете получить доступ к базе данных путем написания соответствующего кода или используя компоненты в форме. Компоненты доступа к данным представляют поля и подключаются путем установки свойства DataSource, которое представляет таблицу и подключается к компонентам баз данных, например TPSQLDatabase, TSQLiteDataSet путем установки свойства DataSet. Компоненты доступа к данным располагаются на вкладке "Data Controls". Источники данных и компоненты доступа к базам данных располагаются на вкладке "Data Access".
44
55## Lazarus и MySQL
66
77### Получение работающего MySQL в Linux или Windows
88
99Следуйте инструкциям в Руководстве пользователя MySQL. Убедитесь в том, что демон mysqld работает надежно, и в том, что все потенциальные пользователи (в том числе root, mysql, вы сами и все остальные, кому это может понадобиться) имеют столько привилегий, сколько им нужно (настолько, насколько это согласуется с безопасностью). Желательно, чтобы все пользователи, включая root, имели пароли. Проверьте действия в системе базы данных, используя примеры, приведенные в руководстве, и убедитесь, что все пользователи действительно имеют надежный доступ.
1010
1111### Работа с MySQL в текстовом режиме
1212
1313В каталоге \$(fpcsrcdir)/packages/base/mysql/ лежит пример программы. Исходники fpc в Lazarus найти можно через меню Окружение –\> Настройки окружения –\> Закладка Файлы –\> Каталог исходного кода FPC. Возможные пути для mysql каталога /usr/share/fpcsrc/packages/base/mysql/ (rpm install), или C:\lazarus\fpcsrc\packages\base\mysql\\ (windows). Этот каталог содержит также модули mysql.pp, mysql_com.pp и mysql_version.pp. Прежде чем запустить тестовый скрипт, нужно создать базу данных с именем testdb: сделайте это, войдя в mysql монитор (в качестве root с полным набором прав), и выполните следующую команду SQL
1414
15-`CREATE DATABASE testdb;`
15+```text
16+CREATE DATABASE testdb;
17+```
1618
1719Затем убедитесь, что все соответствующие пользователи имеют соответствующие права доступа к этой базе данных
1820
19-`GRANT ALL ON testdb TO johnny-user IDENTIFIED BY 'johnnyspassword'; `
21+```text
22+GRANT ALL ON testdb TO johnny-user IDENTIFIED BY 'johnnyspassword';
23+```
2024
2125Существует скрипт, называемый mkdb, попробуйте его запустить:
2226
23-`sh ./mkdb`
27+```text
28+sh ./mkdb
29+```
2430
2531Скорее всего, из этого ничего не выйдет, потому что система не позволит анонимному пользователю получить доступ к базе данных. Измените скрипт с помощью текстового редактора таким образом, чтобы строка запуска mysql выглядела так:
2632
27-`mysql -u root -p  ${1-testdb} << EOF >/dev/null`
33+```text
34+mysql -u root -p ${1-testdb} << EOF >/dev/null
35+```
2836
2937и запустите его еще раз, когда появится запрос – введите пароль. Возможно, вам удалось создать тестовую базу данных, проверьте ее, войдя в mysql монитор и введя следующую команду
3038
31-`select * from FPdev;`
39+```text
40+select * from FPdev;
41+```
3242
3343Вы увидите таблицу с ID, именами пользователя и email-адресами некоторых разработчиков FPC.
3444
3545Теперь попробуйте запустить тестовую программу testdb.pp (возможно, придется ее скомпилировать и весьма вероятно, что с первой попытки это не удастся!!).
3646
3747Я обнаружил, что программа не может соединиться с mysql по нескольким причинам:
3848
3949- Моя система (SuSE Linux v9.0) содержит mysql v4.0.15, а не версию 3, для которой был разработан пакет доступа к mysql.
4050- Программе требуется имя пользователя и пароль для доступа к базе данных.
4151- Компилятору хочется знать, где можно найти библиотеки mysql (ЕСЛИ ВЫ ДО СИХ ПОР НЕ УСТАНОВИЛИ БИБЛИОТЕКИ РАЗРАБОТЧИКА MYSQL, СДЕЛАЙТЕ ЭТО ПРЯМО СЕЙЧАС!)
4252
4353Я создал копию testdb.pp с именем trydb.pp, не редактируя оригинал – это означает, что исходные файлы еще получат исправления в последующих обновлениях CVS. Также я скопировал файлы в каталоге mysql/ver40/ в основной каталог mysql/, переименовав их в mysql_v4.pp, mysql_com_v4.pp и mysql_version_v4.pp, будучи уверенным в переименовании каждого модуля соответственно. Я изменил uses в trydb.pp на
4454
45-`uses mysql_v4`
55+``` pascal
56+uses mysql_v4
57+```
4658
4759и в mysql_v4.pp на
4860
49-`uses mysql_com_v4`
61+``` pascal
62+uses mysql_com_v4
63+```
5064
5165Я добавил строку в /etc/fpc.cfg, показывающую на мои библиотеки:
5266
53-`-Fl/lib;/usr/lib`
67+```text
68+-Fl/lib;/usr/lib
69+```
5470
5571В следующем шаге, возможно, не будет необходимости, если библиотеки разработчика установлены в качестве ссылок, но проверить не помешает. Мне пришлось найти подлинное имя из библиотеки mysqlclint в /usr/lib каталоге, и в моем случае мне пришлось выдать команду:
5672
57-`ln -s libmysqlclient.so.12.0.0 lmysqlclient`
73+```text
74+ln -s libmysqlclient.so.12.0.0 lmysqlclient
75+```
5876
5977чтобы создать символическую ссылку, позволяющую FPC найти библиотеку. Также я создал ссылку
6078
61-`ln -s libmysqlclient.so.12.0.0 mysqlclient`
79+```text
80+ln -s libmysqlclient.so.12.0.0 mysqlclient
81+```
6282
6383и поместил аналогичные ссылки в других каталогах: не то, чтобы очень уж необходимо, но на всякий случай. Некоторым пользователям, возможно, придется добавить следующую ссылку
6484
65-`ln -s libmysqlclient.so.12.0.0 libmysqlclient.so`
85+```text
86+ln -s libmysqlclient.so.12.0.0 libmysqlclient.so
87+```
6688
6789Я изменил trydb.pp – включил реквизиты пользователя, стартовый хост, имя пользователя и пароль как константы:
6890
69-`const`\
70-` host : Pchar= 'localhost';`\
71-` user : Pchar= 'myusername';`\
72-` passwd: Pchar = 'mypassword';`
91+``` pascal
92+const
93+ host : Pchar= 'localhost';
94+ user : Pchar= 'myusername';
95+ passwd: Pchar = 'mypassword';
96+```
7397
7498Я также обнаружил, что не могу соединиться с mysql, используя вызов mysql_connect() и мне приходится использовать вызов функции mysql_real_connect(), которая имеет гораздо больше параметров. Дальнейшее осложняется тем, что количество параметров изменилось между версией 3 (их было семь) и версией 4 (стало восемь). Перед использованием mysql_real_connect мне пришлось использовать mysql_init(), который не нашелся в оригинале mysql.pp но имеется в mysql_v4.pp.
7599
76100Ну вот и код для подключения к базе данных:
77101
78-`{ a few extra variables}`\
79-`var`\
80-`  alloc : PMYSQL;`\
102+``` pascal
103+{ a few extra variables}
104+var
105+ alloc : PMYSQL;
81106
82-`{main program fragment}`\
107+{main program fragment}
83108
84-`begin`\
85-` if paramcount=1 then`\
86-` begin`\
87-`   Dummy:=Paramstr(1)+#0;`\
88-`   DataBase:=@Dummy[1];`\
89-` end;`\
109+begin
110+ if paramcount=1 then
111+ begin
112+ Dummy:=Paramstr(1)+#0;
113+ DataBase:=@Dummy[1];
114+ end;
90115
91-` Writeln ('Allocating Space...');`\
92-` alloc := mysql_init(PMYSQL(@qmysql));`\
93-` Write ('Connecting to MySQL...');`\
94-` sock :=  mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);`\
95-` if sock=Nil then`\
96-` begin`\
97-`   Writeln (stderr,'Couldnt connect to MySQL.');`\
98-`   Writeln (stderr, 'Error was: ', mysql_error(@qmysql));`\
99-`   halt(1);`\
100-` end;`\
101-` Writeln ('Done.');`\
102-` Writeln ('Connection data:');`\
103-`{$ifdef Unix}`\
104-` writeln ('Mysql_port      : ',mysql_port);`\
105-` writeln ('Mysql_unix_port : ',mysql_unix_port);`\
106-`{$endif}`\
107-` writeln ('Host info       : ',mysql_get_host_info(sock));`\
108-` writeln ('Server info     : ',mysql_stat(sock));`\
109-` writeln ('Client info     : ',mysql_get_client_info);`\
116+ Writeln ('Allocating Space...');
117+ alloc := mysql_init(PMYSQL(@qmysql));
118+ Write ('Connecting to MySQL...');
119+ sock := mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);
120+ if sock=Nil then
121+ begin
122+ Writeln (stderr,'Couldnt connect to MySQL.');
123+ Writeln (stderr, 'Error was: ', mysql_error(@qmysql));
124+ halt(1);
125+ end;
126+ Writeln ('Done.');
127+ Writeln ('Connection data:');
128+{$ifdef Unix}
129+ writeln ('Mysql_port : ',mysql_port);
130+ writeln ('Mysql_unix_port : ',mysql_unix_port);
131+{$endif}
132+ writeln ('Host info : ',mysql_get_host_info(sock));
133+ writeln ('Server info : ',mysql_stat(sock));
134+ writeln ('Client info : ',mysql_get_client_info);
110135
111-` Writeln ('Selecting Database ',DataBase,'...');`\
112-` if mysql_select_db(sock,DataBase) < 0 then`\
113-` begin`\
114-`   Writeln (stderr,'Couldnt select database ',Database);`\
115-`   Writeln (stderr,mysql_error(sock));`\
116-`   halt (1);`\
117-` end;`\
118-` {... as original contents of testdb.pp}`
136+ Writeln ('Selecting Database ',DataBase,'...');
137+ if mysql_select_db(sock,DataBase) < 0 then
138+ begin
139+ Writeln (stderr,'Couldnt select database ',Database);
140+ Writeln (stderr,mysql_error(sock));
141+ halt (1);
142+ end;
143+ {... as original contents of testdb.pp}
144+```
119145
120146Теперь готовы к компиляции trydb.pp?
121147
122-`fpc trydb`
148+```text
149+fpc trydb
150+```
123151
124152Успешно! Запускаем:
125153
126-`./trydb`
154+```text
155+./trydb
156+```
127157
128158У-у-у-е-е-е-е! Я попал в список разработчиков FPC! Несколько дополнительных уточнений: сделать ввод реквизитов пользователя и mysql команд интерактивным, с помощью переменных, а не констант, и позволить вводить SQL команды, пока не подадим команду выхода: см. полный листинг программы [см. полный листинг программы](http://wiki.lazarus.freepascal.org/Lazarus_Database_Tutorial/TryDbpp), в которой реквизиты пользователя вводятся из консоли, и программа входит в цикл, где SQL команды вводятся в консоли (без закрывающей запятой), и результаты выводятся до тех пор, пока с клавиатуры не будет введена команда "quit". Листинг консольного вывода [здесь](http://wiki.lazarus.freepascal.org/Lazarus_Database_Tutorial/SampleListingSee)
129159
130160### Подключение к MySQL из приложения Lazarus
131161
132162Данное руководство показывает, как Lazarus подключается к базе данных MySQL и выполняет простые запросы, используя основные компоненты Lazarus. Использования компонент отображения данных не будет, покажем только принцип взаимодействия с базами данных.
133163
134164Создайте новый проект в Lazarus:
135165
136-`Project -> New Project -> Application`
166+```text
167+Project -> New Project -> Application
168+```
137169
138170Автоматически сгенерируется новая форма..
139171
140172Растяните форму на пол-экрана и переименуйте ее и ее заголовок в 'TryMySQL'.
141173
142174Расположите на форме сверху слева три компонента TEdit с вкладки Standard и над каждым из них поместите компонент TLabel. Задайте им заголовки 'Host' (и имена HostLLabel, HostEdit), 'UserName' (UserLabel, UserEdit) и 'Password' (PasswdLabel и PasswdEdit). Как вариант вы можете использовать компонент TLabelledEdit с закладки Additional.
143175
144176Найдите свойство PasswordChar у компонента PasswdEdit, измените его на * или любой другой символ, это приведет к тому, что когда вы вводите пароль, то вместо пароля будет отображаться именно этот символ (несколько символов). Убедитесь, что свойство Text у этого компонента не содержит текста.
145177
146178Теперь расположите еще один компонент Tedit и TLabel в правом верхнем углу формы. Измените заголовок на 'Enter SQL Command' и переименуйте компонент в CommandEdit.
147179
148180Поместите на форму три кнопки, две слева под компонентами TEdit и одну справа под компонентом для команд.
149181
150182Измените свойства Label (Name) левых кнопок на 'Connect to Database' (ConnectButton) и 'Exit' (ExitButton) и правой - 'Send Query' (QueryButton).
151183
152184Расположите большой TMemo с заголовком 'Results' (ResultMemo) слева внизу так, чтобы он заполнил все оставшееся место. Найдите свойство ScrollBars и установите значение ssAutoBoth, чтобы компонент мог прокручивать текст и вертикально и горизонтально. Свойство WordWrap установите в True.
153185
154186Поместите на форму статусную строку (TStatusBar с закладки Common Controls) внизу формы и впишите в свойство SimpleText строку 'TryMySQL'.
155187
156188[Вот что должно получится](http://lazarus-ccr.sourceforge.net/kbdata/trymysqldb.png)
157189
158190Теперь нам потребуется написать несколько обработчиков.
159191
160192У нас на форме слева три компонента TEdit для ввода имени хоста, пользователя и пароля. Как только в них будут введены необходимые данные, нужно нажать на кнопку Connect. Обработчик OnClick для этой кнопки частично базируется на модуле для FPC, который мы привели выше.
161193
162194Результаты запросов к базе данных не могут быть сразу выведены с помощью операторов Pascal write или writeln, сначала их необходимо преобразовать в строки и вывести в компонент TMemo.
163195
164196Хотя операторы Pascal write и writeln и приспособлены для преобразования типов «на лету», использование компонента TMemo для вывода текста требует прямого преобразования типов в строковую форму, так переменные типа Pchar должны быть преобразованы в строки путем использования StrPas, и числа должны конвертироваться функцией IntToStr.
165197
166198Добавим строки в TMemo используя
167199
168-`procedure ShowString (S : string);`\
169-`(* display a string in a Memo box *)`\
170-`begin`\
171-`      trymysqlForm1.ResultsMemo.Lines.Add (S)`\
172-`end;`
200+``` pascal
201+procedure ShowString (S : string);
202+(* display a string in a Memo box *)
203+begin
204+ trymysqlForm1.ResultsMemo.Lines.Add (S)
205+end;
206+```
173207
174208Таким образом, обработчик ConnectButton становится следующим:
175209
176-`procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);`\
177-`(* Connect to MySQL using user data from Text entry boxes on Main Form *)`\
178-`var strg: string;`\
210+``` pascal
211+procedure TtrymysqlForm1.ConnectButtonClick(Sender: TObject);
212+(* Connect to MySQL using user data from Text entry boxes on Main Form *)
213+var strg: string;
179214
180-`begin`\
215+begin
181216
182-` dummy1 :=  trymysqlForm1.HostEdit.text+#0;`\
183-` host := @dummy1[1];`\
184-` dummy2 := trymysqlForm1.UserEdit.text+#0;`\
185-` user := @dummy2[1] ;`\
186-` dummy3 := trymysqlForm1.PasswdEdit.text+#0;`\
187-` passwd := @dummy3[1] ;`\
188-` alloc := mysql_init(PMYSQL(@qmysql));`\
189-` sock :=  mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);`\
190-` if sock=Nil then`\
191-`   begin`\
192-`     strg :='Couldnt connect to MySQL.'; showstring (strg);`\
193-`     Strg :='Error was: '+ StrPas(mysql_error(@qmysql)); showstring (strg);`\
194-`  end`\
195-`   else`\
196-`   begin`\
197-`     trymysqlForm1.statusBar1.simpletext := 'Connected to MySQL';`\
198-`     strg := 'Now choosing database : ' + database; showstring (strg);`\
199-`{$ifdef Unix}`\
200-`     strg :='Mysql_port      : '+ IntToStr(mysql_port); showstring (strg);`\
201-`     strg :='Mysql_unix_port : ' + StrPas(mysql_unix_port); showstring (strg);`\
202-`{$endif}`\
203-`     Strg :='Host info       : ' + StrPas(mysql_get_host_info(sock));`\
204-`     showstring (strg);`\
205-`     Strg :='Server info     : ' + StrPas(mysql_stat(sock)); showstring (strg);`\
206-`     Strg :='Client info     : ' + Strpas(mysql_get_client_info);  showstring (strg);`\
207-` `\
208-`     trymysqlForm1.statusbar1.simpletext := 'Selecting Database ' + DataBase +'...';`\
209-` if mysql_select_db(sock,DataBase) < 0 then`\
210-` begin`\
211-`   strg :='Couldnt select database '+ Database; ShowString (strg);`\
212-`   Strg := mysql_error(sock); ShowString (strg);`\
213-` end`\
214-` end;`\
215-`end;`
217+ dummy1 := trymysqlForm1.HostEdit.text+#0;
218+ host := @dummy1[1];
219+ dummy2 := trymysqlForm1.UserEdit.text+#0;
220+ user := @dummy2[1] ;
221+ dummy3 := trymysqlForm1.PasswdEdit.text+#0;
222+ passwd := @dummy3[1] ;
223+ alloc := mysql_init(PMYSQL(@qmysql));
224+ sock := mysql_real_connect(alloc, host, user, passwd, database, 0, nil, 0);
225+ if sock=Nil then
226+ begin
227+ strg :='Couldnt connect to MySQL.'; showstring (strg);
228+ Strg :='Error was: '+ StrPas(mysql_error(@qmysql)); showstring (strg);
229+ end
230+ else
231+ begin
232+ trymysqlForm1.statusBar1.simpletext := 'Connected to MySQL';
233+ strg := 'Now choosing database : ' + database; showstring (strg);
234+{$ifdef Unix}
235+ strg :='Mysql_port : '+ IntToStr(mysql_port); showstring (strg);
236+ strg :='Mysql_unix_port : ' + StrPas(mysql_unix_port); showstring (strg);
237+{$endif}
238+ Strg :='Host info : ' + StrPas(mysql_get_host_info(sock));
239+ showstring (strg);
240+ Strg :='Server info : ' + StrPas(mysql_stat(sock)); showstring (strg);
241+ Strg :='Client info : ' + Strpas(mysql_get_client_info); showstring (strg);
242+
243+ trymysqlForm1.statusbar1.simpletext := 'Selecting Database ' + DataBase +'...';
244+ if mysql_select_db(sock,DataBase) < 0 then
245+ begin
246+ strg :='Couldnt select database '+ Database; ShowString (strg);
247+ Strg := mysql_error(sock); ShowString (strg);
248+ end
249+ end;
250+end;
251+```
216252
217253Поле для ввода справа позволяет вводить команды SQL без завершающей точки-с-запятой; как только вы удовлетворитесь синтаксисом - жмите кнопку SendQuery - запрос выполнится и результат будет отображен в компоненте ResultsMemo.
218254
219255Обработчик SendQuery опять же базируется на версии FPC, за исключением использования преобразования типов для последующего отображения строк.
220256
221257Разница между программой на FPC и этой программой в том, что в случае возникновения ошибки программа на Free Pascal завершит свою работу и сессия MySQL останется открытой, в то же время во второй программе контроль вернется в главную форму и можно повторить попытку. В конечном итоге приложение нормально завершает свою работу (закрывая при этом сессию MySQL) при нажатии кнопки Exit.
222258
223259Ниже приведен код обработчика кнопки SendQuery:
224260
225-`procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject);`\
226-`var`\
227-` dumquery, strg: string;`\
228-`begin`\
229-`    dumquery := TrymysqlForm1.CommandEdit.text;`\
230-`    dumquery := dumquery+#0;`\
231-`    query := @dumquery[1];`\
232-`    trymysqlForm1.statusbar1.simpletext := 'Executing query : '+ dumQuery +'...';`\
233-`    strg := 'Executing query : ' + dumQuery; showstring (strg);`\
234-`    if (mysql_query(sock,Query) < 0) then`\
235-`    begin`\
236-`      Strg :='Query failed '+ StrPas(mysql_error(sock)); showstring (strg);`\
237-`    end`\
238-`    else`\
239-`    begin`\
240-`      recbuf := mysql_store_result(sock);`\
241-`      if RecBuf=Nil then`\
242-`      begin`\
243-`        Strg :='Query returned nil result.'; showstring (strg);`\
244-`      end`\
245-`      else`\
246-`      begin`\
247-`        strg :='Number of records returned  : ' + IntToStr(mysql_num_rows (recbuf));`\
248-`        Showstring (strg);`\
249-`        Strg :='Number of fields per record : ' + IntToStr(mysql_num_fields(recbuf));`\
250-`        showstring (strg);`\
251-`        rowbuf := mysql_fetch_row(recbuf);`\
252-`        while (rowbuf <>nil) do`\
253-`        begin`\
254-`             Strg :='(Id: '+ rowbuf[0]+', Name: ' + rowbuf[1]+ ', Email : ' +`\
255-`              rowbuf[2] +')';`\
256-`             showstring (strg);`\
257-`             rowbuf := mysql_fetch_row(recbuf);`\
258-`        end;`\
259-`      end;`\
260-`    end;`\
261-`end;`
261+``` pascal
262+procedure TtrymysqlForm1.QueryButtonClick(Sender: TObject);
263+var
264+ dumquery, strg: string;
265+begin
266+ dumquery := TrymysqlForm1.CommandEdit.text;
267+ dumquery := dumquery+#0;
268+ query := @dumquery[1];
269+ trymysqlForm1.statusbar1.simpletext := 'Executing query : '+ dumQuery +'...';
270+ strg := 'Executing query : ' + dumQuery; showstring (strg);
271+ if (mysql_query(sock,Query) < 0) then
272+ begin
273+ Strg :='Query failed '+ StrPas(mysql_error(sock)); showstring (strg);
274+ end
275+ else
276+ begin
277+ recbuf := mysql_store_result(sock);
278+ if RecBuf=Nil then
279+ begin
280+ Strg :='Query returned nil result.'; showstring (strg);
281+ end
282+ else
283+ begin
284+ strg :='Number of records returned : ' + IntToStr(mysql_num_rows (recbuf));
285+ Showstring (strg);
286+ Strg :='Number of fields per record : ' + IntToStr(mysql_num_fields(recbuf));
287+ showstring (strg);
288+ rowbuf := mysql_fetch_row(recbuf);
289+ while (rowbuf <>nil) do
290+ begin
291+ Strg :='(Id: '+ rowbuf[0]+', Name: ' + rowbuf[1]+ ', Email : ' +
292+ rowbuf[2] +')';
293+ showstring (strg);
294+ rowbuf := mysql_fetch_row(recbuf);
295+ end;
296+ end;
297+ end;
298+end;
299+```
262300
263301Сохраните свой проект и жмите Запуск -\> Запуск
264302
265303Полный листинг программы доступен [тут](http://lazarus-ccr.sourceforge.net/kbdata/mysqldemo.tar.gz)
266304
267305## Lazarus и PostgreSQL
268306
269307Очень краткое руководство по подключению Lazarus 0.9.12 (или более поздней версии) к базе данных PostgreSQL, локально или удаленно, используя компонент TPQConnection.
270308
271309- После корректной установки, выполните следующие шаги:
272310 - Поместите на форму компоненты PQConnection, SQLQuery, SQLTransaction с вкладки SQLdb
273311 - Поместите компонент DataSource с вкладки DataAccess
274312 - Поместите DBGrid с вкладки DataControls
275313
276314- В компоненте PQConnection заполните свойства:
277315 - transaction – ссылкой на объект SQLTransaction
278316 - DatabaseName
279317 - HostName
280318 - UserName + password
281319
282320Проверьте, что SQLTransaction автоматически привязался к PQConnection
283321
284322- В компоненте SQLQuery заполните свойства:
285323 - transaction соответствующим объектом
286324 - database
287325 - SQL (что-то вроде 'select * from anytable')
288326
289327В компоненте DataSource установите свойство DataSet который должен указываить на объект SQLQuery В компоненте DBGrid установите в свойстве datasource указатель на объект DataSource Включайте и активируйте все. DBGrid должен показать данные прямо во время разработки. TDBText и TDBEdit работают, но у меня только отображают данные. Для внесения изменений в базу данных я вызываю запрос вставки для базы напрямую, используя следующий код:
290328
291-`try`\
292-`  sql:= 'UPDATE table SET setting=1';`\
293-`  PQDataBase.Connected:=True;`\
294-`  PQDataBase.ExecuteDirect('Begin Work;');`\
295-`  PQDataBase.ExecuteDirect(sql);`\
296-`  PQDataBase.ExecuteDirect('Commit Work;');`\
297-`  PQDataBase.Connected:=False;`\
298-`except`\
299-`  on E : EDatabaseError do`\
300-`    MemoLog.Append('DB ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);`\
301-`  on E : Exception do`\
302-`    MemoLog.Append('ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);`\
303-`end;`
329+``` pascal
330+try
331+ sql:= 'UPDATE table SET setting=1';
332+ PQDataBase.Connected:=True;
333+ PQDataBase.ExecuteDirect('Begin Work;');
334+ PQDataBase.ExecuteDirect(sql);
335+ PQDataBase.ExecuteDirect('Commit Work;');
336+ PQDataBase.Connected:=False;
337+except
338+ on E : EDatabaseError do
339+ MemoLog.Append('DB ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
340+ on E : Exception do
341+ MemoLog.Append('ERROR:'+sql+chr(13)+chr(10)+E.ClassName+chr(13)+chr(10)+E.Message);
342+end;
343+```
304344
305345Примечания: Проверено в Windows, Lazarus 0.9.12 + PgSQL 8.3.1 Некоторые тесты в linux, Lazarus 0.9.12 и PgSQL 8.0.x
306346
307347Установка и ошибки: В тестируемой версии Lazarus .12, поля типа "text" и "numeric" имеют ошибки Я без проблем использовал строки фиксированной длины, int и float8 Иногда перезапуск Lazarus позволяет обойти тупые ошибки... После каких-то ошибок транзакция может остаться активной и требуется ручное ее закрытие Изменения, сделанные в Lazarus, конечно же не видны до тех пор, пока транзакция не завершена (commit) Встроенный отладчик немного глюкавый (по крайней мере в windows) – иногда внешний (запущенный помимо IDE) может помочь найти ошибки. В Линукс некоторые сообщения об ошибках выводятся в консоль – запускайте вашу программу в командной строке, иногда можно получить немного полезной отладочной информации. Ошибка: "Can not load Postgresql client. Is it installed (libpq.so) ?" Добавьте путь для поиска libpq* из инсталляции PostgreSQL. В Linux добавьте путь к файлу libpq.so в секцию libraries в файле /etc/fpc.cfg file. Например: -Fl/usr/local/pgsql/lib В windows, добавьте пути к библиотекам в переменную Path или в папку проекта В windows я копировал все DLLs из папки C:\Program Files\PostgreSQL\8.1\bin в папку, которая была в переменной PATH Или добавьте папку postgres\bin в path.
308348
309349## Lazarus и SQLite
310350
311351Luiz Américo
312352
313353Посетите страничку [sqlite4fpc](http://sqlite4fpc.yolasite.com/), чтобы найти описание API и дополнительную документацию.
314354
315355TSqliteDataset и TSqlite3Dataset сейчас входят в стандартную поставку Lazarus.
316356
317357### Введение
318358
319359TSqliteDataset и TSqlite3Dataset являются потомками TDataset, предоставляющими доступ к базам данных SQLite версий 2.8.x и 3.x.x соответственно. Ниже перечислены основные достоинства и недостатки:
320360
321361Достоинства:
322362
323363- Гибкость: программист может выбирать - использовать или нет язык SQL, что позволяет ему работать с простым макетом таблицы или с комплексным макетом любой сложности, насколько это позволяет SQL/sqlite
324364- Автоматическое обновление данных: нет необходимости обновлять данные вручную, используюя команды SQL - один метод берет на себя все заботы
325365- Скорость: данные кэшируются в оперативной памяти, что позволяет быстрее просматривать данные
326366- Не требуется установка/настройка сервера: просто поставляйте программу вместе с библиотекой sqlite
327367
328368Недостатки:
329369
330370- Требуется дополнительный файл (библиотека sqlite).
331371
332372### Требования
333373
334374- Для баз данных sqlite2:
335375 - fpc 2.0.0 или выше
336376 - Lazarus 0.9.10 или выше
337377 - runtime-библиотека sqlite 2.8.15 или выше (можно взять с [www.sqlite.org](http://www.sqlite.org))
338378
339379- Для баз данных sqlite3:
340380 - fpc 2.0.2 или выше
341381 - Lazarus 0.9.11 (svn revision 8443 или выше)
342382 - runtime-библиотека sqlite 3.2.1 или выше (можно взять с [www.sqlite.org](http://www.sqlite.org))
343383
344384Прежде чем начать проект lazarus, убедитесь что:
345385
346386- библиотека sqlite доступна по пути PATH или находится в каталоге программы
347387- под Linux, используйте cmem первым модулем в предложении uses главной программы (модуля проекта)
348388 - В Debian, Ubuntu и других Debian-like дистрибутивах (также относится к OpenSuse), в целях сборки Lazarus IDE вы должны установить пакеты libsqlite-dev/libsqlite3-dev, не только sqlite/sqlite3.
349389
350390### Как работать (Основы)
351391
352392Установите пакет из каталога /components/sqlite (смотрите инструкцию) (Пакет → Настройка установленных пакетов → установить sqlite3laz)
353393
354394Во время разработки установите следующие свойства:
355395
356396- FileName: путь к файлу базы данных \[обязательно\]
357397- TableName: название таблицы используемой в sql выражении \[обязательно\]
358398- Sql: SQL select выражение \[необязательно\]
359399
360400**Создание таблицы (Dataset)**
361401
362402Сделайте двойной щелчок мышкой по иконке компонента или используйте пункт 'Create Table' в выпадающем меню, которое появляется после щелчка правой кнопкой мыши по компоненту. Перед Вами появится окно редактора таблицы.
363403
364404Ниже даны все типы данных поддерживаемые TSqliteDataset и TSqlite3Dataset:
365405
366406- Integer
367407- AutoInc
368408- String
369409- Memo
370410- Bool
371411- Float
372412- Word
373413- DateTime
374414- Date
375415- Time
376416- LargeInt
377417- Currency
378418
379419**Получение данных**
380420
381421После создания таблицы, откройте базу данных методом Open. Если свойство SQL не установлено, то будут выбраны все записи из всех полей, что эквивалентно следующему SQL выражению:
382422
383-`SQL:='Select * from TABLENAME'; `
423+``` pascal
424+SQL:='Select * from TABLENAME';
425+```
384426
385427**Закрепление изменений в файле базы данных**
386428
387429Используйте метод ApplyUpdates. При этом dataset должно содержать минимум одно поле которое требуется для Первичного Ключа (значения поля должны быть UNIQUE и не NULL) Это возможно достичь двумя путями:
388430
389431- Установите свойство PrimaryKey, дав ему имя поля, которое будет Первичным Ключом
390432- Добавьте поле типа AutoInc (Это поле часто используется в TSqliteDataSet автоматически как Первичный Ключ)
391433
392434Если одно из двух действий выполнено, вызывайте
393435
394-`ApplyUpdates;`
436+```text
437+ApplyUpdates;
438+```
395439
396440PS1: Если выполнены оба действия, то для ApplyUpdates используется поле установленное в свойстве PrimaryKey.
397441
398442PS2: Установка поля в PrimaryKey которое не является Первичным Ключём может привести к повреждению данных при вызове ApplyUpdates. Так же убедитесь, что используемое поле содержит уникальные и не Null значения перед тем как использовать это.
399443
400444### Примечания
401445
402446- Хотя это было проверено с таблицей в 10000 записей и работало прекрасное, однако TSqliteDataset хранит все данные в памяти, так что не забудьте извлекать только необходимые данные (это в первую очередь касается Memo Полей)
403447- Один и тот же файл данных (свойство Filename) может содержать несколько таблиц/наборов данных
404448- Несколько наборов данных (различные комбинации полей) могут быть созданы, используя одну и ту же таблицу одновременно
405449- Возможно фильтровать данные используя оператор WHERE в sql выражении, закрывая и вновь открывая набор данных (или вызывая метод RefetchData). Но в этом случае расположение и число полей должны оставаться одинаковыми
406450- Также возможно применение сложных операторов SQL, используя псевдонимы, объединения, представления из нескольких таблиц (помните, что они должны постоянно находится в том же файле данных), но в этом случае ApplyUpdates не будет работать. Если кто-то хочет использовать сложные запросы и применить обновления файла данных, сообщите мне по почте и я дам некоторые советы, как это сделать
407451- Устанавить имя файла при несозданном sqlite2.x файле данных и если после открыть TSqliteDataset, то это возможно, но у некоторых полей не будут обнаружены правильный тип поля. Они будут обработаны как строковые поля.
408452
409453Примеры для sqlite можно найти в каталоге fpc/fcl/db/sqlite
410454
411455Luiz Américo pascalive(at)bol(dot)com(dot)br
412456
413457## Lazarus и MSSQL
414458
415459На сегодняшний день с MSSQL можно работь через:
416460
417461- встроенный драйвер SQLDB (последний Lazarus/FPC 2.6.1+ из исходников, недоступен как stable download): TMSSQLConnection (MS SQL) и TSybaseConnection (Sybase ASE)
418462- Zeos (свежий CVS, см. ссылки на Zeos на данной странице)
419463- ODBC (MS SQL и Sybase ASE)
420464
421465Пожалуйста, обратитесь к справке FPC и Lazarus, чтобы подробнее узнать про SQLDB для Sybase ASE и MS SQL Server.
422466
423467## Lazarus и Firebird / Interbase
424468
425469Посмотрите [Установка пакетов](http://wiki.lazarus.freepascal.org/Install_Packages). На этой странице расположен небольшой пример для начинающих, как соединиться с сервером FireBird или InterBase.
426470
427471### FBLib Firebird Library
428472
429473[FBLib](http://fblib.altervista.org/) - это OpenSource библитотека для непосредственного доступа к серверу из Borland Delphi / Kylix, Freepascal и Lazarus.
430474
431475Текущая реализация включает:
432476
433477- Непосредственный доступ к Firebird 1.0.x, 1.5.x и 2.0 Classic или SuperServer
434478- Кроссплатформенность \[Win32,Gnu/Linux,FreeBSD)
435479- Автоматический выбор клиентской библиотеки 'fbclient' или 'gds32'
436480- Запросы с параметрами
437481- Поддержка SQL диалектов 1 и 3
438482- LGPL лицензия
439483- Получение метаданных
440484- Простой синтаксический анализатор скриптов
441485- Добавляется только 100-150 KБ к экзешнику
442486- Поддержка BLOB-полей
443487- Выгрузка данных в HTML, SQL-скрипт
444488- Сервисные функции (backup,restore,gfix...)
445489- Обработчик событий
446490
447491Вы можете загрузить документацию с сайта [FBLib's website](http://fblib.altervista.org/).
448492
449493## Lazarus и dBase
450494
451495Tony Maro
452496
453497Вы можете также посетить [[Lazarus Tdbf Tutorial/ru|TDbf Страница руководства]].
454498
455499FPC содержит простой компонент базы данных под названием "TDbf", который функционально подобен компоненту TTable в Delphi ([вебсайт TDbf](http://tdbf.sourceforge.net/)), поддерживающий все основные функции по работе с файлами dBase. Этот компонент не устанавливается по умолчанию, поэтому Вы должны сами установить пакет из каталога "lazarus/components/tdbf" и пересобрать Lazarus. Он появится рядом с компонентом TDatasource на вкладке "Data Access".
456500
457501Компонент TDbf имеет преимущество перед другими компонентами баз данных, т.к. не требует никаких внешних библиотек, однако это не самая лучшая идея для больших приложений баз данных.
458502
459503Компонент очень удобен в применении. Просто поместите TDbf на свою форму, установите путь к каталогу, в котором будут Ваши файлы базы данных, задайте название таблицы, и свяжите его с Вашим компонентом TDatasource.
460504
461505Реальная программа требует немного большего усилия, как бы то ни было. Если таблица ещё не существует, то Вы должны будете её создать программно до открытия. **Примечание**: Версия OpenOffice 2.0x и выше содержит OpenOffice Base, которое может создать dbf файлы более дружественным способом.
462506
463507Попытка открыть несуществующую таблицу вызовет ошибку. Таблицы могут быть созданы программно через компонент после того, как во время выполнения будут заданы путь и название таблицы.
464508
465509Например, чтобы создать таблицу с названием "dvds", чтобы сохранить Вашу dvd коллекцию, Вы поместите компонент на свою форму, установите во время выполнения путь к каталогу с базой и установите название таблицы в "dvds". Получающийся файл будет назван "dvds.dbf". В свой код вставьте такие строки:
466510
467511``` pascal
468512 Dbf1.FilePathFull := '/path/to/my/database';
469513 Dbf1.TableName := 'dvds';
470514 With Dbf1.FieldDefs do begin
471515 Add('Name', ftString, 80, True);
472516 Add('Description', ftMemo, 0, False);
473517 Add('Rating', ftString, 5, False);
474518 end;
475519 Dbf1.CreateTable;
476520```
477521
478522Когда этот код будет выполнен, cоздасться таблица коллекции DVD. После этого данные можно будет отображать в компонентах просмотра данных, связав их через TDatasource с этим компонентом.
479523
480524Добавление индексов является немного отличным от типичного TTable. Это должно быть сделано после того, как база данных открыта. Этот же метод используется и для того, чтобы перестроить индексы. Например:
481525
482526``` pascal
483527 Dbf1.Exclusive := True;
484528 Dbf1.Open;
485529 Dbf1.AddIndex('dvdsname','Name',[ixPrimary, ixUnique, ixCaseInsensitive]);
486530 Dbf1.AddIndex('rating.ndx', 'Rating', [ixCaseInsensitive]);
487531 Dbf1.Close;
488532```
489533
490534Первичный индекс будет файлом с названием "dvdsname.mdx", а второй будет файл с названием "rating.ndx". Однако в базе данных с множеством таблиц, Вы должны позаботиться об уникальности имени файлов индексов.
491535
492536**Примечание**. Для версий dBase, которые поддерживают несколько индексов в одном файле, расширение в имени индекса указывать не надо, только имя индекса. Тогда все индексы будут созданы в одном файле с названием таким же, как и имя таблицы, но с расширением ".mdx".
493537
494538Для того, чтобы указать конкретную версию таблицы, нужно задать свойство TDbf.TableLevel.
495539
496540### Поиск и отображение набора данных
497541
498542Simon Batty
499543
500544В этом примере я хочу найти в базе данных книг все названия, у которых есть автор и затем отобразить список в мемобоксе:
501545
502546``` pascal
503547Dbf1.FilePathFull := '/home/somelocatio/database_location/'; // путь к базе данных
504548 Dbf1.TableName := 'books.dbase'; // файл таблицы, включая расширение
505549 DbF1.Open;
506550 memo1.Clear; // очистка мемобокса
507551
508552 Dbf1.FilterOptions := [foCaseInsensitive];
509553 Df1.Filter := 'AU=' + QuotedStr('anauthor'); // AU это поле, где содержится имя автора
510554
511555 Dbf1.Filtered := true; // Включаем фильтрование
512556 Dbf1.First; // Переходим в начало отфильтрованных данных
513557 while not dbf1.EOF do // В цикле проходим весь полученый набор данных
514558 begin
515559 memo1.Append(Dbf1.FieldByName('TI').AsString); //TI это поле названий
516560 dbf1.next; // Переход на следующую запись
517561 end;
518562
519563Dbf1.Close;
520564```
521565
522566Заметьте, что Вы можете использовать Ddf1.findfirst, чтобы перейти на первую запись в отфильтрованном наборе, затем используйте Dbf1.next, чтобы перемещаться по данным. Я нашел, что использование Dbf1.Findnext подвешивает программуь.
523567
524568## Ссылки, связанные с этой статьей
525569
526570- [[Databases|Создание приложений для баз данных с помощью Lazarus используя модуль DB]]\
527571- [[MySQLDatabases|Создание приложений для баз данных MySQL]]\
528572- [[Zeos tutorial|Создание приложений баз данных с использованием компонентов Zeos]]
529573- [Pascal Data Objects](http://pdo.sourceforge.net) API для доступа к базам данных программами FPC и Delphi, и использующие родную библиотеку MySQL версий 4.1 и 5.0, и Firebird SQL 1.5 и 2.0. Сделано на подобие класса PDO в PHP.
530574
531575## Ответственность и изменения
532576
533577Эта страница сформирована из epikwiki [version](http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusDatabase).
534578
535579---
536580*From the Free Pascal wiki, page "Lazarus Database Tutorial/ru", as it stood on 2020-02-18 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history