Rozdział 17. Bazy danych dbExpress
Adam Boduch
W poprzednim rozdziale omawiałem korzystanie z baz danych przy użyciu komponentów BDE. Inną ? moim zdaniem ciekawą ? formą dostępu do baz danych jest technologia dbExpress. Dzięki komponentom z zakładki dbExpress możesz w prosty sposób uzyskać dostęp do najpopularniejszych systemów baz danych, takich jak MS SQL, MySQL, Interbase i Oracle.
1 Aplikacje klient-serwer
1.1 Narzędzia
1.2 Komponenty
2 Łączenie z serwerem
2.3 Kontrola procesu logowania
2.4 Zdarzenia AfterConnect i AfterDisconnect
3 Jak działa MySQL?
3.5 Tabele
3.6 Zapytania
4 Tworzenie tabel
5 Dodawanie rekordów
6 Kasowanie rekordów
6.7 Procedura kasująca
7 Odczytywanie rekordów
7.8 Przykładowy program
8 Zmiana wartości rekordów
8.9 Przykładowy program: spis sprzedanych towarów
9 Inne komponenty dbExpress
10 Programy oparte o dbExpress
11 Podsumowanie
Podstawą korzystania z różnych baz danych są tzw. sterowniki, które umożliwiają dostęp do systemów baz i pełnią rolę pośredników.
Ważnym czynnikiem wpływającym na jakość technologii dbExpress jest to, że są to komponenty międzyplatformowe, zapewniające zgodność z Delphi oraz ze środowiskiem Kylix.
W tym rozdziale:
*dowiesz się, na czym polega tworzenie aplikacji typu klient-serwer;
*nauczysz się komunikować z bazą danych MySQL;
*zaprojektujesz prostą aplikację baz danych, łączącą się z serwerem.
Aplikacje klient-serwer
Architektura baz danych typu klient-serwer polega na łączeniu aplikacji-klienta z serwerem, na którym znajduje się centralna baza danych. Zasada ta jest podobna do omawianej w rozdziale 11. komunikacji za pomocą gniazd. Różnica polega na tym, że na serwerze jest zainstalowany jakiś system baz danych, a my możemy tylko się z nim połączyć.
SQL to skrót od angielskich słów Structured Query Language. Jest to język oparty na specjalnych zapytaniach kierowanych do bazy.
Narzędzia
Podczas pisania tego rozdziału i przygotowywania przykładowych programów posłużę się darmowymi narzędziami, które może łatwo zdobyć każdego, kto ma dostęp do Internetu. Jako serwer wykorzystamy serwer lokalny Apache 1.3. Baza danych oparta będzie na MySQL. Po pierwsze, baza danych MySQL jest dość łatwa w użyciu, bardzo popularna, darmowa i stosunkowo szybka. Serwer Apache także jest darmowy i niezwykle popularny. Oba te programy dostępne są zarówno w wersjach dla Linuksa, jak i dla Windows.
Najnowsza wersja serwera Apache znajduje się na stronie www.apache.org, natomiast serwer baz danych MySQL możesz pobrać ze strony www.mysql.com. Sposób instalacji Apache oraz MySQL możesz znaleźć m.in. na stronie www.4programmers.net. Ze względu na dość znaczne rozmiary tych aplikacji postanowiłem ? z myślą o Czytelnikach, którzy posiadają modemy ? umieścić te aplikacje na dołączonej do książki płycie CD-ROM.
Komponenty
W przykładach z tego rozdziału wykorzystamy komponenty bazodanowe z zakładki dbExpress. Owe komponenty są raczej łatwe w użyciu, jeżeli pozna się zasadę ich działania. Na początku połączenie się z serwerem może sprawić niewielkie problemy, lecz później wszystko powinno pójść gładko.
Łączenie z serwerem
Do połączenia z serwerem MySQL będziemy musieli użyć komponentu TSQLConnection
z zakładki dbExpress.
Pierwsza rzecz, jaką musisz zrobić, to skopiowanie do katalogu z programem biblioteki libmysql.dll, która jest wymagana do połączenia. Ów plik możesz znaleźć w pakiecie MySQL jak również na dołączonej do książki płycie CD-ROM, w katalogu ../listingi/17/Connect.
Umieść więc komponent TSQLConnection
na formularzu i zmień jego nazwę na MySQL. Następnie będziesz musiał zmienić wartość właściwości ConnectionName
na MySQLConnection
(rysunek 17.1); spowoduje to automatyczne dopasowanie kilku pozostałych właściwości.
Rysunek 17.1. Lista możliwych połączeń
Komponent odczytuje listę sterowników z plików dbxconnections.ini oraz dbxdrivers.ini (u mnie te pliki znajdują się w katalogu E:\Borland Shared\DBExpress). Pliki INI zawierają także parametry, które są wczytywane do właściwości Params w Inspektorze Obiektów.
Aby móc nawiązać połączenie, należy zmodyfikować jeszcze odpowiednie wartości we właściwości Params. Wybierz tę właściwość ? zostanie wyświetlone okno edycji parametrów, takie jak na rysunku 17.2.
Rysunek 17.2. Okno edycji parametrów
W tym momencie powinieneś uruchomić serwer MySQL i stworzyć w nim jakąś przykładową bazę danych ? np. delphi.
W oknie edycji parametrów w pozycji Host Name
wpisz adres serwera ? w moim przypadku jest to 127.0.0.1. Pozycja Database
określa bazę danych, na jakiej odbędą się operacje ? wpisz tutaj nazwę utworzonej bazy danych, czyli delphi. Pozostało jeszcze określenie nazwy użytkownika bazy oraz hasło (pola User_Name
oraz Password
). Wpisz tutaj nazwę użytkownika i hasło do swojej bazy danych. W moim przypadku ani hasło, ani nazwa użytkownika nie są wymagane, mogę więc usunąć te pola z edytora.
Połączenie ustanowić można poprzez właściwość Connected komponentu TSQLConnection
. Właściwość Connected
jest typu Boolean
? przypisanie jej wartości True spowoduje próbę połączenia z serwerem:
procedure TMainForm.btnConnectClick(Sender: TObject);
begin
if MySQL.Connected then
MySQL.Connected := False
else MySQL.Connected := True;
end;
Wykonanie powyższego kodu spowoduje albo rozłączenie, albo połączenie z bazą danych ? w zależności od aktualnego stanu.
W przypadku zmiany właściwości LoginPromt
na False
podczas łączenia nie zostanie wyświetlone okno logowania. Program pobierze nazwę użytkownika oraz hasło z parametrów User_Name
oraz Password
.
Jeżeli dostęp do Twojej bazy nie wymaga nazwy użytkownika ani hasła, usuń klucze User_Name
oraz Password
z okna edytora właściwości (rysunek 17.2).
Kontrola procesu logowania
Nie każdy chce, aby przed zalogowaniem komponent wyświetlał okienko, w którym trzeba podać nazwę użytkownika i hasło. Lepszym rozwiązaniem jest umieszczenie na formularzu dwóch etykiet, w których użytkownik będzie mógł wprowadzić swoje hasło oraz nazwę użytkownika. To zadanie można zrealizować, korzystając ze zdarzenia OnLogin
:
procedure TMainForm.MySQLLogin(Database: TSQLConnection;
LoginParams: TStrings);
begin
LoginParams.Values['User_Name'] := edtLogin.Text;
LoginParams.Values['password'] := edtPassword.Text;
end;
Zdarzenie to występuje zawsze przed zalogowaniem się do systemu. Powoduje ono przypisanie nazwy użytkownika oraz hasła z etykiet tekstowych.
Zdarzenia AfterConnect i AfterDisconnect
Aby sprawdzić, czy program został już połączony z bazą danych, wystarczy wygenerować dwa zdarzenia: AfterConnect
oraz AfterDisconnect
. Oba występują po zawarciu połączenia oraz po rozłączeniu z serwerem (rysunek 17.3):
procedure TMainForm.MySQLAfterConnect(Sender: TObject);
begin
StatusBar.SimpleText := 'Połączony ...';
end;
procedure TMainForm.MySQLAfterDisconnect(Sender: TObject);
begin
StatusBar.SimpleText := 'Rozłączony...';
end;
Rysunek 17.3. Tekst informujący o nawiązaniu połączenia
Jak działa MySQL?
Przed przystąpieniem do dalszych działań musisz opanować podstawy oraz zasady działania bazy danych MySQL.
MySQL (www.mysql.com) jest darmową, opartą na licencji GNU platformą baz danych. Swoją popularność zawdzięcza głównie temu, że jest darmowa ? również w zastosowaniach komercyjnych. Stały rozwój tego programu zapewniają setki programistów, współpracujących przy tworzeniu oraz poprawianiu tej bazy danych.
Tabele
Baza danych jest pojęciem o wielu znaczeniach. W systemie MySQL baza danych jest zbiorem tabel. Natomiast tabela jest uporządkowanym zbiorem kolumn i wierszy, niczym tabela w programie Excel albo Word (rysunek 17.4).
Rysunek 17.4. Zasada działania tabel
Na powyższym rysunku przedstawiona jest tabela składająca się z trzech kolumn i zawierająca dwa rekordy. Taka sama idea zastosowana jest w bazach danych (w tym MySQL). Myślę, że to pojęcie jest dla Ciebie już w miarę jasne, chociażby po lekturze poprzedniego rozdziału o aplikacjach BDE.
Zapytania
Z wydawaniem ?rozkazów? bazie danych wiąże się pojęcie zapytań. Zapytania przekazywane do bazy danych nakazują jej wykonanie pewnych czynności: utworzenia tabeli, dodania kolumny, usunięcia kolumny, wstawienia nowego rekordu (wiersza) czy usunięcia bazy danych. Aby zapytanie zostało prawidłowo zinterpretowane przez bazę danych, musi być skonstruowane według odpowiedniej składni. Przykładowo zapytanie nakazujące stworzenie nowej tabeli wygląda tak:
CREATE TABLE users (
id int(11) NOT NULL auto_increment,
name varchar(128) NOT NULL default '',
mail varchar(128) NOT NULL default '',
UNIQUE KEY id (id)
)
Tworzona tabela będzie się nazywać users oraz będzie posiadać trzy kolumny: id (identyfikator rekordu), name i mail. Przeznaczeniem tej tabeli jest przechowywanie informacji na temat zarejestrowanych użytkowników, a zatem kolumna name może określać nazwę użytkownika (pseudonim, imię lub nazwisko), a mail adres e-mail wpisującej się osoby.
Numer id jest zwiększany za każdym dodaniem rekordu (auto_increment). Maksymalna liczba znaków, jaką może zawierać dana kolumna, to 128 (varchar(128)) ? żadna z kolumn nie może być pusta (NOT NULL
), a domyślna wartość to ciąg pusty (default ''). Kolumna id będzie unikatowa (UNIQUE
).
MySQL nie rozróżnia małych i wielkich liter w zapytaniach. Oznacza to, że zapytania CREATE TABLE i create table zostaną zinterpretowane tak samo.
Tworzenie tabel
Do utworzenia tabeli przez nasz program będziemy potrzebowali komponentu TSQLDataSet
; umieść go na formularzu i nazwij SQL. Kolejnym krokiem jest wybranie z listy SQLConnection
komponentu MySQL
.
Zapytanie można ustawić we właściwości CommandText
, zaznaczając ową właściwość, a następnie naciskając przycisk wielokropka, co spowoduje otwarcie edytora takiego, jak na rysunku 17.5.
Rysunek 17.5. Edytor zapytań
W polu SQL wpisz takie oto zapytanie:
CREATE TABLE users (
id int(11) NOT NULL auto_increment,
name varchar(128) NOT NULL default '',
mail varchar(128) NOT NULL default '',
UNIQUE KEY id (id)
)
Możesz już zamknąć edytor; wpisane zapytanie spowoduje utworzenie tabeli users.
Żeby wysłać zapytanie, należy użyć funkcji ExecDir
z naszego komponentu SQL.
Utworzenie tabeli (wysłanie zapytania) realizowane jest przez ten kod:
procedure TMainForm.btnCreateTableClick(Sender: TObject);
begin
if SQL.ExecSQL(True) = 0 then MessageDlg('Tabela utworzona!', mtInformation, [mbOK], 0);
end;
Funkcja ExecSQL
zwraca cyfrę 0, jeżeli operacja się powiodła.
Dodawanie rekordów
Wstawienie rekordu do istniejącej już tabeli odbywa się za pośrednictwem zapytania INSERT
. Jeżeli znamy dane, które chcemy umieścić w tabeli, to sformułowanie zapytania nie powinno przysporzyć problemu:
INSERT users SET name='Adam Boduch',mail='adam@boduch.net'
Zwróć uwagę, że nie musimy podawać pierwszego parametru ? id. Baza MySQL automatycznie nada wartość kolumnie id, gdyż przypisaliśmy jej parametr auto_increment.
Na formularzu możesz umieścić dwie etykiety tekstowe, w których użytkownik będzie mógł podać swoje imię oraz adres e-mail (rysunek 17.6). Kod programu prezentuje listing 17.1.
Rysunek 17.6. Dodawanie nowego rekordu do bazy
Listing 17.1. Kod źródłowy programu
{
Copyright (c) 2002 by Adam Boduch <adam@4programmers.net>
}
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBXpress, DB, SqlExpr, StdCtrls, FMTBcd;
type
TMainForm = class(TForm)
MySQL: TSQLConnection;
btnConnect: TButton;
SQL: TSQLDataSet;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
edtLogin: TEdit;
edtMail: TEdit;
btnAdd: TButton;
procedure btnConnectClick(Sender: TObject);
procedure MySQLAfterConnect(Sender: TObject);
procedure MySQLAfterDisconnect(Sender: TObject);
procedure btnAddClick(Sender: TObject);
private
Connected : Boolean;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.btnConnectClick(Sender: TObject);
begin
if Connected then Connected := False else Connected := True;
MySQL.Connected := Connected;
end;
procedure TMainForm.MySQLAfterConnect(Sender: TObject);
begin
btnConnect.Caption := 'Rozłącz';
end;
procedure TMainForm.MySQLAfterDisconnect(Sender: TObject);
begin
btnConnect.Caption := 'Połącz';
end;
procedure TMainForm.btnAddClick(Sender: TObject);
var
SQLQuery : String;
begin
SQLQuery := Format('INSERT INTO users SET name="%s", mail="%s"', [edtLogin.Text, edtMail.Text]);
SQL.CommandText := SQLQuery;
if SQL.ExecSQL(True) = 1 then MessageDlg('Rekord został dodany!', mtInformation, [mbOK], 0);
end;
end.
Na samym początku konieczne staje się odpowiednie sformułowanie zapytania (czyli łańcucha), którego wartość przydzielimy właściwości CommandText
komponentu TSQLDataSet
. Rekord powinien zostać wstawiony do bazy po wykonaniu funkcji ExecSQL
.
Jeśli wstawienie zostanie wykonane pomyślnie, funkcja ExecSQL
zwróci wartość różną od 0.
Kasowanie rekordów
Jeżeli uznamy, że przy wstawianiu nowej pozycji pomyliliśmy się lub nie jest ona nam już potrzebna ? możemy ją z łatwością usunąć. Do tego służy zapytanie DELETE
. Formułując zapytanie, należy podać dane, według których baza usunie rekord (np. numer ID):
DELETE FROM users WHERE id='1'
Takie zapytanie może być tworzone na różny sposób ? tj. różne warunki mogą spowodować usunięcie danych. Kryterium może być nazwa użytkownika:
DELETE FROM users WHERE name='Adam Boduch'
W powyższym przypadku usunięte zostaną wszystkie rekordy, w których kolumna name ma wartość Adam Boduch
. Aby zaostrzyć kryterium usuwania danych, można zastosować operatory AND
i OR
(tak samo, jak w Delphi)
DELETE FROM users SET name='Adam' AND mail='adam@boduch.net'
W końcu może istnieć wiele rekordów, w których kolumna name ma wartość Adam
, prawda? Żeby nie usunąć niepotrzebnie danych, zastosujemy operator AND
w celu podania również wartości kolumny mail.
Procedura kasująca
W naszym przypadku najlepiej usuwać rekord, biorąc pod uwagę kolumnę id, która w żadnym wypadku nie będzie się powtarzać:
procedure TMainForm.btnDeleteClick(Sender: TObject);
begin
SQL.CommandText := 'DELETE FROM users where id="1"';
SQL.ExecSQL(True);
end;
Odczytywanie rekordów
Chyba najtrudniejszym zadaniem w przypadku dbExpress jest odczytywanie rekordów. Samo dbExpress jest w gruncie rzeczy proste do opanowania, lecz odczyt danych wymaga poświęcenia większej ilości czasu i wierszy kodu.
Sam odczyt jest realizowany przez zapytanie SELECT:
SELECT * FROM users
Taka instrukcja pobiera wszystkie rekordy znajdujące się w bazie danych. Możliwe jest zaostrzenie tego kryterium i odczytanie tylko wybranych fragmentów:
SELECT * FROM users WHERE name='Adam'
Powyższe zapytanie wyświetli jedynie rekordy zawierające w kolumnie name wartość Adam
.
Po wysłaniu zapytania odczyt konkretnych elementów z tabeli odbywa się za pomocą właściwości FieldValues:
SQL.FieldValues['name']
Nazwę kolumny, którą chcemy odczytać, należy wstawić w nawiasie kwadratowym. Wartość zwracana przez ową właściwość jest typu Variant
, więc znika problem konwersji pomiędzy typami (w przypadku, gdyby np. kolumna id była typu Integer).
Jeśli mamy odczytać wiele rekordów, należy to uczynić w pętli for
:
for I := 1 to SQL.RecordCount do
begin
{ dodaj kolejne wartości }
ListItem := ListView.Items.Add;
ListItem.Caption := IntToStr(SQL.FieldValues['id']);
ListItem.SubItems.Add(SQL.FieldValues['name']);
ListItem.SubItems.Add(SQL.FieldValues['mail']);
SQL.Next;
end;
Właściwość RecordCount
zawiera ilość rekordów, które zostały zwrócone przez bazę ? jeśli znamy tę liczbę, możemy rozwiązać problem odczytania wszystkich wierszy.
Zwróć uwagę na przedostatni wiersz ? wywołanie instrukcji Next
z komponentu TSQLDataSet
. Bez tej instrukcji odczytanie kolejnego rekordu nie byłoby możliwe ? w wyniku jej wykonania komponent przechodzi do następnego elementu.
Przykładowy program
Przed czytaniem wszystkich elementów zwróconych przez bazę należy wywołać metodę Open komponentu TSQLDataSet, a po zakończeniu operacji ? procedurę Close
. Pełny kod programu zaprezentowano w listingu 17.2.
Listing 17.2. Odczytywanie oraz kasowanie rekordów z bazy danych
{
Copyright (c) 2002 by Adam Boduch <adam@4programmers.net>
}
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBXpress, DB, SqlExpr, StdCtrls, FMTBcd, Grids, ValEdit,
ComCtrls;
type
TMainForm = class(TForm)
MySQL: TSQLConnection;
btnConnect: TButton;
SQL: TSQLDataSet;
ListView: TListView;
btnDelete: TButton;
procedure btnConnectClick(Sender: TObject);
procedure MySQLAfterConnect(Sender: TObject);
procedure MySQLAfterDisconnect(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnDeleteClick(Sender: TObject);
private
Connected : Boolean;
procedure LoadTable;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.btnConnectClick(Sender: TObject);
begin
if Connected then Connected := False else Connected := True;
MySQL.Connected := Connected;
end;
procedure TMainForm.MySQLAfterConnect(Sender: TObject);
begin
btnConnect.Caption := 'Rozłącz';
btnDelete.Enabled := True;
LoadTable;
end;
procedure TMainForm.MySQLAfterDisconnect(Sender: TObject);
begin
btnConnect.Caption := 'Połącz';
btnDelete.Enabled := False;
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// podczas zamknięcia programu ? rozłączenie z serwerem
MySQL.Connected := False;
end;
procedure TMainForm.LoadTable;
var
i : Integer;
ListItem : TListItem;
begin
ListView.Items.Clear;
SQL.CommandText := 'SELECT * FROM users'; // zapytanie
SQL.Open; // odczytaj dane
for I := 1 to SQL.RecordCount do
begin
{ dodaj kolejne wartości }
ListItem := ListView.Items.Add;
ListItem.Caption := IntToStr(SQL.FieldValues['id']);
ListItem.SubItems.Add(SQL.FieldValues['name']);
ListItem.SubItems.Add(SQL.FieldValues['mail']);
SQL.Next;
end;
SQL.Close;
end;
procedure TMainForm.btnDeleteClick(Sender: TObject);
begin
SQL.CommandText := Format('DELETE FROM users where id="%s"', [ListView.Selected.Caption]);
SQL.ExecSQL(True);
LoadTable; // po wykonaniu zapytania ? wywołaj procedurę
end;
end.
Zwróć uwagę, że program oprócz odczytania elementów z bazy danych do komponentu TListView
k potrafi także te elementy usuwać ? służy do tego przycisk btnDelete
.
Sam program w działaniu jest przedstawiony na rysunku 17.7.
Rysunek 17.7. Dane odczytane z serwera MySQL
Zmiana wartości rekordów
W celu zmiany wartości rekordów wystarczy wysłać do bazy zapytanie SQL UPDATE
.
UPDATE users SET name='adam@boduch.net'
Powyższe zapytanie uaktualni wartość kolumny name ? nada jej wartość adam@boduch.net. Problem w tym, że uaktualnienie obejmie wszystkie wiersze danej tabeli. Aby zmienić wartość jednego tylko rekordu, należy dodać warunek WHERE
:
UPDATE users SET name='adam@boduch.net' where ID='1'
W powyższym przypadku uaktualnienie dotyczyć będzie jedynie rekordu o wartości ID równej 1.
SQL.CommandText := 'UPDATE users SET name="Jan Kowalski" WHERE name="Adam Boduch"';
SQL.ExecSQL(True);
Powyższy fragment kodu spowoduje uaktualnienie wszystkich rekordów, w których kolumnie name znajduje się łańcuch Adam Boduch
. Nowa wartość kolumny name to od tego momentu Jan Kowalski
.
Przykładowy program: spis sprzedanych towarów
Na dołączonej do książki płycie CD-ROM znajduje się program wykorzystujący bazę MySQL do umieszczania na serwerze listy sprzedanych towarów. Baza danych przechowuje informację na temat nazwy towaru, ilości sprzedanych sztuk, ceny oraz daty wykonania transakcji. Zapytanie SQL, realizujące stworzenie odpowiedniej tabeli, wygląda tak:
CREATE TABLE towary (
id int(11) NOT NULL auto_increment,
towar char(255) NOT NULL default '',
sztuk smallint(2) NOT NULL default '0',
cena float NOT NULL default '0',
data datetime NOT NULL default '0000-00-00 00:00:00',
UNIQUE KEY id (id)
) TYPE=MyISAM;
Kolumna cena będzie typu zmiennoprzecinkowego, a data ? typu datetime, który umożliwia przechowywanie dat i czasu.
Program będzie się składał z dwóch formularzy: jeden posłuży do odczytywania danych i przedstawienia ich w komponencie TListView
, a drugi będzie służył do dodawania nowych rekordów. W praktyce jest to podsumowanie tego wszystkiego, co zaprezentowałem w poprzednich podpunktach rozdziału. Kody źródłowe obu formularzy przedstawione są w listingach 17.3 i 17.4.
Listing 17.3. Kod źródłowy modułu MainFrm.pas
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, DBXpress, FMTBcd, DB, SqlExpr;
type
TMainForm = class(TForm)
ListView: TListView;
GroupBox1: TGroupBox;
btnConnect: TButton;
btnInsert: TButton;
btnRemove: TButton;
SQL: TSQLConnection;
Query: TSQLDataSet;
procedure btnInsertClick(Sender: TObject);
procedure btnConnectClick(Sender: TObject);
procedure btnRemoveClick(Sender: TObject);
private
public
procedure LoadTable;
end;
var
MainForm: TMainForm;
implementation
uses InsertFrm;
{$R *.dfm}
procedure TMainForm.btnInsertClick(Sender: TObject);
begin
{ wyświetl formularz służący do dodawania kolejnych rekordów }
InsertForm := TInsertForm.Create(Application);
InsertForm.ShowModal;
InsertForm.Free;
end;
procedure TMainForm.LoadTable;
var
i : Integer;
ListItem : TListItem;
begin
ListView.Items.Clear;
Query.CommandText := 'SELECT * FROM towary'; // odczytanie danych z tabeli
Query.Open;
{ przedstaw informacje w komponencie TListView }
for I := 0 to Query.RecordCount do
begin
ListItem := ListView.Items.Add;
ListItem.Caption := Query.FieldValues['id'];
ListItem.SubItems.Add(Query.FieldValues['towar']);
ListItem.SubItems.Add(Query.FieldValues['sztuk']);
ListItem.SubItems.Add(Query.FieldValues['cena'] + ' zł');
ListItem.SubItems.Add(Query.FieldValues['data']);
Query.Next;
end;
Query.Close;
end;
procedure TMainForm.btnConnectClick(Sender: TObject);
begin
SQL.Connected := True; // połącz
LoadTable;
SQL.Connected := False;
end;
procedure TMainForm.btnRemoveClick(Sender: TObject);
begin
SQL.Connected := True; // połącz
Query.CommandText := Format('DELETE FROM users where id="%s"', [ListView.Selected.Caption]);
Query.ExecSQL(True);
LoadTable; // po wykonaniu zapytania ? wywołaj procedurę
SQL.Connected := False; // rozłącz z serwerem
end;
end.
Listing 17.4. Kod źródłowy modułu InsertFrm.pas
unit InsertFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TInsertForm = class(TForm)
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
btnInsert: TButton;
edtThi: TEdit;
edtCount: TEdit;
edtPrice: TEdit;
procedure btnInsertClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
InsertForm: TInsertForm;
implementation
uses MainFrm;
{$R *.dfm}
procedure TInsertForm.btnInsertClick(Sender: TObject);
begin
with MainForm do
begin
SQL.Connected := True; // połącz z serwerem
// wyślij zapytanie
Query.CommandText := Format('INSERT INTO towary SET towar="%s",sztuk="%s",cena="%s",data=NOW()',
[edtThi.Text, edtCount.Text, edtPrice.Text]);
Query.ExecSQL(True);
LoadTable; // ponownie wyświetl zawartość tabeli
SQL.Connected := False;
Close;
end;
end;
end.
W przypadku, gdy masz na dysku dwie wersje Delphi ? 6 oraz 7 ? mogą pojawić się problemy w korzystaniu z dbExpress, np. błąd Operation Not Supported.
Inne komponenty dbExpress
W zakładce dbExpress ? oprócz komponentów TSQLConnction
oraz TSQLDataSet
? znajdują się również komponenty TSQLQuery
, TSQLStoredProc
, TSQLTable
, TSQLMonitor
i TSQLSimpleDataSet
. Ciekawym komponentem jest TSQLMonitor
. Umożliwia on monitorowanie komend przesyłanych pomiędzy komputerami za pomocą komponentu TSQLConnection.
Umieść na formularzu komponent TSQLMonitor
i z listy rozwijalnej właściwości SQLConnection
wybierz komponent typu TSQLConnection
. Zdarzenie OnLogTrace
komponentu SQLMonitor
występuje w trakcie komunikacji między komputerami.
procedure TMainForm.SQLMonitorLogTrace(Sender: TObject;
CBInfo: pSQLTRACEDesc);
begin
Memo.Lines := SQLMonitor.TraceList;
end;
Jak widzisz, w prosty sposób można listę wiadomości wyświetlić w komponencie Memo
. SQLMonitor
posiada bowiem właściwość TraceList
typu TStringList
, która zawiera wszystkie wiadomości.
Aby komponent SQLMonitor
zaczął działać, należy zmienić właściwość Active
na True
.
W zdarzeniu OnAfterConnect komponentu TSQLConnection
wpisz przykładowy kod, który wykona jakieś zapytanie SQL.
SQL.CommandText := 'SELECT * FROM users;
SQL.ExecSQL(True);
Zapytanie SELECT
nic nie wnosi do programu, gdyż nie można używać metody ExecSQL ? ma ona za zadanie wykonanie pewnych czynności, które będziemy obserwować podczas działania programu w komponencie Memo. Rysunek 17.8 przedstawia program podczas działania.
Rysunek 17.8. Monitorowanie SQL
Komponent TSQLMonitor
posiada przydatną właściwość FileName
. Dzięki niej monitorowane wiadomości mogą być automatycznie dodawane do pliku określonego właśnie we właściwości FileName
.
Pozostałe komponenty z zakładki dbExpress nie oferują nic ponad to, co komponent TSQLDataSet
; funkcjonują podobnie jak ich odpowiedniki w BDE.
Programy oparte o dbExpress
Sterowniki baz danych pakietu dbExpress są zawarte w oddzielnych bibliotekach DLL. W celu przeniesienia całej aplikacji na inny komputer należy dołączyć pewne pliki *.dll. Jakie? O tym informuje tabela 17.1.
Tabela 17.1. Biblioteki DLL wymagane w połączeniu z różnymi bazami danych
Biblioteka | Przeznaczenie |
---|---|
dbexpdb2.dll | Bazy danych DB |
dbexpmysql.dll | Bazy danych MySQL |
dbexpmss.dll | Bazy danych MS SQL |
dbexpora.dll | Bazy danych Oracle |
dbexpinf.dll | Sterowniki Informix |
dbexpint.dll | Bazy danych Interbase |
Podsumowanie
Technologia dbExpress jest bardzo efektywna i dość łatwa w użyciu ? zapewnia dostęp do wielu baz danych. Pewnie jeszcze wielokrotnie skorzystasz z dbEpxress i nieraz usłyszysz o tej technologii.
Załączniki:
Więcej informacji Delphi 2005. Kompendium programisty Adam Boduch Format: B5, stron: 1048 oprawa twarda Zawiera CD-ROM |
Wsadziłem plik libmysql.dll do Borland/Delphi7/Lib i wywala mi błąd przy prubie polączenia
http://oi53.tinypic.com/2litwkj.jpg
Ej, przed chwilą ściągnąłem plik libmysql.dll (bo mi wywalalo że go nie może załadować) i dalej mi tak pisze
"Unable to Load libmysql.dll"
HELP!
Skąd można ściągnąć komponenty dbExpress do delphi 7 personal?
Niestety przy SQL.Open; wyskakuje dbExpress Error: [0x0003]: Invalid Field Type
NIEROZUMIE! błąd mi nie pasuje do akcji ale na 100% po tej linijce wyskakuje
Chce byc dobrze zrozumiany (bo tytul moze wskazywac inaczej), dbExpress to nie system bazodanowy, a jedynie technologia.