InterBase i Delphi 7 - programowanie baz danych
Artur
Witam - bardzo mało jest artykułów poświeconych tej tematyce a na forum powtarzają się pytania dotyczące Delphi i InterBase więc wychodzę naprzeciw i postanowiłem napisać artykuł. A więc zaczynamy
Zakładam że każdy ma zainstalowane Delphi, ja mam Delphi 7 i wszystkie poniższe przykłady będą tworzone w takiej wersji. Proponuję zainstalować InterBase - ja zainstalowałem InterBase 6 (W1-V6.0.1.0) - razem z serwerem baz danych (po zainstalowniu koło Tray'a pojawia się ikonka) instaluje się klient czyli program IBConsole - za pomocą tego programu można zarządzać bazą danych. Praktycznie wszystko wykonuje się w nim za pomocą języka SQL. A więc uruchamiamy IBConsole - następnie klikamy na InterBase Servers wtedy pojawia sie okienko w którym musimy podać login i hasło aby zalogowac się na serwerze InterBase (jesli nic nie zmienialiśmy to jest to użytkownik SYSDBA i hasło masterkey).
Następnie z menu głównego programu wybieramy DataBase->Create DataBase
i wpisujemy alias i ewentualnie ścieżkę do pliku ja wpisałem następujące alias: koledzy i filename: H:\Documents and Settings\hawk\Pulpit\baza\ZNAJOMI.GDB - rozszerzenie gdb jest rozszerzeniem historycznym - można stosować inne rozszerzenia ale ja jestem wierny umowom :). Teraz klikamy Ok i mamy już bazę danych utworzoną. Stwórzmy teraz tabelę przechowującą informacje o znajmych (oczywiście użyjemy SQL-a). Wybieramy z menu głównego IBConsole Tools->Interactive SQL i w górnej części okna wpisujemy:
CREATE TABLE znajomi
(
Id_znajomego INTEGER NOT NULL,
Imie VARCHAR(20) NOT NULL,
Nazwisko VARCHAR(30) NOT NULL,
Adres VARCHAR(50) NOT NULL,
Telefon VARCHAR(20),
Komorka VARCHAR(20),
Email VARCHAR(20),
PRIMARY KEY(Id_znajomego)
);
Nie będe dokładnie opisywał składni każdego polecenia SQL - odsyłam do pomocy InterBase lub do jakiejś książki o SQL-u. Nie będę także opisywał teoretycznych aspektów projektowania baz danych. Powiem tylko że powyższa tabela nie do końca spełnia założenia tworzenia baz danych - ale jest to tylko przykład.
Klikamy przycisk Execute Query(Ctrl+E) i już mamy utworzoną tabelę.
Teraz przechodzimy do Delphi i spróbujmy napisać program obsługujący naszą bazę danych. Naszą aplikacje oprzemy na technologii IBX (InterBase Express). W Delphi 7 są dwie zakładki z komponentami InterBase i InterBase Admin.
Oki zaczynamy.
Wrzucamy na Formę komponent
IBDatabase1, IBQuery1, IBTransaction1, DataSource1(z zakładki Data Access) i DBGrid1 (z zakładki Data Control)
Ustawiamy właściwości dl tych komponentów:
dla IBDatabase1
ustawiamy właściwość DatabaseName na utworzony przed chwilą plik bazy danych H:\Documents and Settings\hawk\Pulpit\baza\ZNAJOMI.GDB.
ustawiamy właściwość DefaultTransaction na IBTransaction1
dla IBQuery1
ustawiamy właściwość Database na IBDataBase1
ustawiamy włąsciwość Transaction na IBTransaction1
klikamy na właściwość SQL i w pole SQL wpisujemy Select * From znajomi //wyświetli nam wszystkie rekordy z tabeli znajomi
dla IBTransaction1
ustawiamy właściwość DefaultDatabase na IBDataBase1
dla DataSource1
ustawiamy właściwość DataSet na IBQuery1
dla DBGrid1
ustawiamy właściwość DataSource na DataSource1
ustawiamy właściwość Option->dgRowSelect na True //żeby zaznaczać cały wiersz tabeli
ustawiamy właściwość ReadOnly na True // tylko do odczytu
Na koniec ustawiamy właściwość Active na True dla IBTransaction1 i dla IBQuery1
i już powinniśmy ujrzeć nagłówki kolumn w tabelce - zapisujemy projekt i kompilujemy
Gdy będziemy próbowali uruchomić program najpierw pojawi się okienko Database Login i trzeba będzie tam wpisać SYSDBA i masterkey (czyli login i hasło dla InterBase). Aby pozbyć się tego natrętnego okienka klikamy dwa razy na komponent IBDataBase1 i wypełniamy pola login: SYSDBA, password: masterkey i odznaczamy "ptaszka" przy opcji Login Prompt. Następnie musimy ponownie ustawić IBQuery1.Active na True;
Gdy teraz uruchomimy program nie zobaczymy już denerwującego okna.
Teraz dwukrotnie klikamy na DBGrid1 i naciskamy przycisk Add All Fields - możemy kliknąć na każde pole i pozmieniać jego właściwości takie jak wyświetlana nazwa (Title->Caption) długość (Width) i tu możemy również sprawić że pole nie będzie wyświetlane Visible na False - ja ustawiłem pole Id_znajomego żeby nie bylo widoczne
Spróbujmy teraz zrobić dodawanie nowej osoby z poziomu naszej aplikacji
Wrzucamy na formę kilka etykiet i kontrolek Edit
w Edit1 - będziemy wpisywać Imię
w Edit2 - będziemy wpisywać Nazwisko
w Edit3 - będziemy wpisywać Adres
w Edit4 - będziemy wpisywać Telefon
w Edit5 - będziemy wpisywać Telefon komórkowy
w Edit6 - będziemy wpisywać Email
Dodajemy przycisk Button1 po nacisnięciu którego będzie dopisywany rekord do bazy danych
Teraz napiszmy procedury odpowiedzialne za wyświetlanie, dodawanie i usuwanie wpisów w bazie danych
procedure zapytanieSelect(zapytanie:String; IBQuery:TIBQuery);
//procedura wykonuje zapytanie SELECT - wyświetla wszystkie dane w tabeli
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.Open; //wykonujemy zapytanie Open dla zapytania typu SELECT
end;
procedure zapytanieDelete(zapytanie:String; tabela:String; IBQuery:TIBQuery; IBDatabase:TIBDataBase);
//procedura usuwa jeden wpis z bazy danych
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.ExecSQL; //wykonujemy zapytanie ExecSQL dla zapytań typu INSERT, UPDATE, DELETE
IBDataBase.Connected:=False; //rozłączamy się z bazą danych - bardzo ważny moment
IBDatabase.Connected:=True; //łączymy się ponownie z bazą danych
zapytanieSelect('SELECT * FROM ' + tabela + ';', Form1.IBQuery1); //wykonujemy zapytanie SELECT w celu wyświetlenia zaktualizowanych rekordów
end;
procedure zapytanieInsert(zapytanie:String;IBQuery:TIBQuery);
//procedura dodaje jeden wpis do bazy danych
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.ExecSQL; //wykonujemy zapytanie ExecSQL dla zapytań typu INSERT, UPDATE, DELETE
end;
function pzapytanieSelect(zapytanie:String;IBQuery:TIBQuery;co:String):string;
//funkcja wykonuje zapytanie SELECT i zwraca wartość pola zadanego jako parametr "co"
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.Open; //wykonujemy zapytanie Open dla zapytania typu SELECT
result:=IBQuery.FieldByName(co).AsString; //zwracamy interesujące nas pole jako wynik funkcji
end;
Bardzo ważne linie kodu zamieszczam ponizej - odpowiedzialne sa ona za rozłączenie i ponowne połączenie z bazą danych. Po co je stosuję? Otóż gdyby ich nie było to po wykonaniu zapytania INSERT nowy wpis zostałby dodany, ale nie zobaczylibyśmy tego - trzeba by było wyłączyć i włączyć program. A po rozłączeniu i ponownym połączeniu sie z bazą danych i wykonaniu zapytania SELECT wszystko działa poprawnie - czyli widać nowododany wpis.
IBDataBase.Connected:=False; //rozłączamy się z bazą danych - bardzo ważny moment
IBDatabase.Connected:=True; //łączymy się ponownie z bazą danych
Mając juz wszystkie niezbędne procedury i funkcji oprogramowujemy zdarzenie naciśnięcia przycisku - dodanie jednego wpisu do bazy danych
procedure TForm1.Button1Click(Sender: TObject);
var klucz_glowny:integer;
begin
if (Edit1.Text<>'') and (Edit2.Text<>'') and (Edit3.Text<>'') then
//sprawdzamy czy wszelkie niezbędne informacje zostały wpisane czy użytkownik uzupełnił pola Imię Nazwisko i Adres - pozostałe pola nie są wymagane
begin
try //zaczynamy blok try - chcemy pobrać maxymalną wartość klucza głownego aby kolejny rekord zapisać pod numerem o 1 większym
klucz_glowny:=StrToInt(pzapytanieSelect('SELECT MAX(ID_znajomego) AS ID FROM znajomi ;',Form1.IBQuery1,'ID')); //zapytanie służące do wybierania maksymalnego numeru
klucz_glowny:=klucz_glowny+1; //zwiększamy o 1 klucz główny (dotychczasowy maksymalny numer)
except
on EConvertError do klucz_glowny:=1; //jeśli w bazie nie było żadnego wpisu to ustawiamy wartość klucza głównego na 1
end;
if not IBTransaction1.InTransaction then
IBTransaction1.StartTransaction; //uruchamiamy transakcę
zapytanieInsert('INSERT INTO znajomi (Id_znajomego,Imie,Nazwisko,Adres,Telefon,Komorka,Email) VALUES ("'+IntToStr(klucz_glowny)+'", "'+Edit1.Text+'", "'+Edit2.Text+'", "'+Edit3.Text+'", "'+Edit4.Text+'", "'+Edit5.Text+'", "'+Edit6.text+'"); ',Form1.IBQuery1); //wywołujemy procedurę dodającą nowe dane do bazy danych
IBTransaction1.Commit;//ustawiamy stan transakcji na Commit czyli wszystko sie udało
end
else
//jęsli użytkownik nie uzupełnił wszystkich wymaganych pól to wyświetlamy komunikat
Showmessage('Uzupeelnij wszystkie pola');
zapytanieSelect('SELECT * FROM znajomi',Form1.IBQuery1,Form1.IBDatabase1);//wyświetlamy wszystkie rekordy - wykonujemy zapytanie SELECT w celu pokazania że nowy wpis został dodany do bazy danych
end;
Ok teraz nadeszła pora żeby zaprogramować usuwanie rekordu z bazy danych - zrobimy to w następujący sposób klikniemy na polu DBGRid1 wpis, który chcemy usunąć i prawym klawiszem myszy wybierzemy opcje usuń wpis - wpis wtedy zostanie usunięty. Aby to zrobić dodajmy nowy komponent - PopupMenu1(menu rozwijane po kliknięciu prawym klawiszem myszy) i dadamy do niego opcję "Usuń wpis" Dla komponentu DBGrid1 zmieniamy właściwość PopupMenu na PopupMenu1.
Następnie stwórzmy zmienną globalną co:string; - będzie ona przechowywała numer osoby który został kliknięty lewym klawiszem myszy. Oprogramujemy zdarzenie onCellClick komponentu DBGrid1
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
co:=DBGrid1.Fields[0].AsString;//jak klikniemy którekolwiek pole w DBGrid to zmienna co bedzie miała wartość przechowywaną w kolumnie Nr dla klikniętego rekordu
end;
Teraz zostaje nam juz tylko oprogramowanie zdarzenia wybrania "usuń wpis" dla menu podręcznego
procedure TForm1.Usuwpis1Click(Sender: TObject);
begin
zapytanieDelete('DELETE FROM znajomi WHERE ID_znajomego =' + co + ';', 'znajomi', Form1.IBQuery1, Form1.IBDatabase1); //wykonujemy zapytanie Delete gdzie Id_znajomego jest równe wartości przechowywanej w zmiennej "co"
end;
Zróbmy jeszcze sortowanie tabeli wg kolumny komponentu DBGrid1, która zostanie kliknieta. W tym celu oprogramowujemy zdarzenie onTitleClick dla komponentu DBGrid1.
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var atrybut, wartosc:string;
begin
atrybut:=Column.Title.Caption; //pobieramy napis kolumny na który klikneliśmy
// w poniższych if-ach liczy sie wielkość liter
if atrybut='Nr' then wartosc:='ID_znajomego'; //w zależności od nazwy kolumny ustawiamy wartość zmiennej "wartość" na pole odpowiadające danej kolumnie przechowywane w baie danych - np jeśli klikniemy kolumnę "Nr" to posortujemy dane wg atrybutu "ID_znajomego"
if atrybut='IMIĘ' then wartosc:='Imie';
if atrybut='NAZWISKO' then wartosc:='Nazwisko';
if atrybut='ADRES' then wartosc:='Adres';
if atrybut='TELEFON' then wartosc:='Telefon';
if atrybut='KOMÓRKA' then wartosc:='Komorka';
if atrybut='EMAIL' then wartosc:='Email';
zapytanieSelect('SELECT * FROM znajomi ORDER BY '+ wartosc +';',Form1.IBQuery1, Form1.IBDatabase1); //wykonujemy zapytanie SELECT z klauzulą ORDER BY sortującą rosnąco dane wg kolumny podanej w parametrze "wartosc"
DBGRid1.Repaint;//odświerzamy DBGrid1
DBGrid1.Refresh;
end;
Aby zrobić zapytanie UPDATE można usunąć dany rekord i dodać ponownie lub zastosować zapytanie UPDATE - ale to już nie jest trudne (mam nadzieję) po lekturze tego artykułu
Poniżej zamieszczam cały kod programu:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, IBDatabase, IBCustomDataSet, IBQuery, Grids, DBGrids, StdCtrls, Menus;
type
TForm1 = class(TForm)
IBDatabase1: TIBDatabase;
DataSource1: TDataSource;
IBQuery1: TIBQuery;
IBTransaction1: TIBTransaction;
DBGrid1: TDBGrid;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Button1: TButton;
PopupMenu1: TPopupMenu;
Usuwpis1: TMenuItem;
procedure Button1Click(Sender: TObject);
procedure DBGrid1CellClick(Column: TColumn);
procedure Usuwpis1Click(Sender: TObject);
procedure DBGrid1TitleClick(Column: TColumn);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
co:string;
implementation
procedure zapytanieSelect(zapytanie:String; IBQuery:TIBQuery; IBDataBase:TIBDataBase);
//procedura wyświetla wszystkie dane w tabeli
begin
IBDataBase.Connected:=False; //rozłączamy się z bazą danych - bardzo ważny moment
IBDatabase.Connected:=True; //łączymy się ponownie z bazą danych
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.Open; //wykonujemy zapytanie Open dla zapytania typu SELECT
end;
procedure zapytanieDelete(zapytanie:String; tabela:String; IBQuery:TIBQuery; IBDatabase:TIBDataBase);
//procedura usuwa jeden wpis z bazy danych
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.ExecSQL; //wykonujemy zapytanie ExecSQL dla zapytań typu INSERT, UPDATE, DELETE
zapytanieSelect('SELECT * FROM ' + tabela + ';', Form1.IBQuery1, Form1.IBDatabase1); //wykonujemy zapytanie SELECT w celu wyświetlenia zaktualizowanych rekordów
end;
procedure zapytanieInsert(zapytanie:String; IBQuery:TIBQuery);
//procedura dodaje jeden wpis do bazy danych
begin
IBQuery.Close; //zamykamy komponent Query - musimy to zrobić
IBQuery.SQL.Clear; //czyścimy treść starego zapytania
IBQuery.SQL.Add(zapytanie); //wpisujemy nowe zapytanie
IBQuery.ExecSQL; //wykonujemy zapytanie ExecSQL dla zapytań typu INSERT, UPDATE, DELETE
end;
function pzapytanieSelect(zapytanie:String;IBQuery:TIBQuery;co:String):string;
begin
IBQuery.Close;
IBQuery.SQL.Clear;
IBQuery.SQL.Add(zapytanie);
IBQuery.Open;
result:=IBQuery.FieldByName(co).AsString;
end;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var klucz_glowny:integer;
begin
if (Edit1.Text<>'') and (Edit2.Text<>'') and (Edit3.Text<>'') then
begin
try
klucz_glowny:=StrToInt(pzapytanieSelect('SELECT MAX(ID_znajomego) AS ID FROM znajomi ;',Form1.IBQuery1,'ID'));
klucz_glowny:=klucz_glowny+1;
except
on EConvertError do klucz_glowny:=1;
end;
if not IBTransaction1.InTransaction then
IBTransaction1.StartTransaction;
zapytanieInsert('INSERT INTO znajomi (Id_znajomego,Imie,Nazwisko,Adres,Telefon,Komorka,Email) VALUES ("'+IntToStr(klucz_glowny)+'", "'+Edit1.Text+'", "'+Edit2.Text+'", "'+Edit3.Text+'", "'+Edit4.Text+'", "'+Edit5.Text+'", "'+Edit6.text+'"); ',Form1.IBQuery1);
IBTransaction1.Commit;
end
else
Showmessage('Uzupeelnij wszystkie pola');
zapytanieSelect('SELECT * FROM znajomi',Form1.IBQuery1,Form1.IBDatabase1);
end;
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
co:=DBGrid1.Fields[0].AsString;
end;
procedure TForm1.Usuwpis1Click(Sender: TObject);
begin
zapytanieDelete('DELETE FROM znajomi WHERE ID_znajomego =' + co + ';', 'znajomi', Form1.IBQuery1, Form1.IBDatabase1);
end;
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var atrybut, wartosc:string;
begin
atrybut:=Column.Title.Caption;
if atrybut='Nr' then wartosc:='ID_znajomego';
if atrybut='IMIĘ' then wartosc:='Imie';
if atrybut='NAZWISKO' then wartosc:='Nazwisko';
if atrybut='ADRES' then wartosc:='Adres';
if atrybut='TELEFON' then wartosc:='Telefon';
if atrybut='KOMÓRKA' then wartosc:='Komorka';
if atrybut='EMAIL' then wartosc:='Email';
zapytanieSelect('SELECT * FROM znajomi ORDER BY '+ wartosc +';',Form1.IBQuery1, Form1.IBDatabase1);
DBGRid1.Repaint;
DBGrid1.Refresh;
end;
end.
Treść pliku Project1.dfm
object Form1: TForm1
Left = 183
Top = 121
Width = 794
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 0
Top = 168
Width = 19
Height = 13
Caption = 'Imi'#281
end
object Label2: TLabel
Left = 120
Top = 168
Width = 46
Height = 13
Caption = 'Nazwisko'
end
object Label3: TLabel
Left = 240
Top = 168
Width = 27
Height = 13
Caption = 'Adres'
end
object Label4: TLabel
Left = 416
Top = 168
Width = 36
Height = 13
Caption = 'Telefon'
end
object Label5: TLabel
Left = 536
Top = 168
Width = 93
Height = 13
Caption = 'Telefon kom'#243'rkowy'
end
object Label6: TLabel
Left = 656
Top = 168
Width = 25
Height = 13
Caption = 'Email'
end
object DBGrid1: TDBGrid
Left = 0
Top = 0
Width = 786
Height = 145
Align = alTop
DataSource = DataSource1
Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit]
PopupMenu = PopupMenu1
ReadOnly = True
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'MS Sans Serif'
TitleFont.Style = []
OnCellClick = DBGrid1CellClick
OnTitleClick = DBGrid1TitleClick
Columns = <
item
Expanded = False
FieldName = 'ID_ZNAJOMEGO'
Title.Caption = 'Nr'
Visible = True
end
item
Expanded = False
FieldName = 'IMIE'
Title.Caption = 'IMI'#280
Visible = True
end
item
Expanded = False
FieldName = 'NAZWISKO'
Visible = True
end
item
Expanded = False
FieldName = 'ADRES'
Width = 200
Visible = True
end
item
Expanded = False
FieldName = 'TELEFON'
Visible = True
end
item
Expanded = False
FieldName = 'KOMORKA'
Title.Caption = 'KOM'#211'RKA'
Visible = True
end
item
Expanded = False
FieldName = 'EMAIL'
Visible = True
end>
end
object Edit1: TEdit
Left = 0
Top = 184
Width = 121
Height = 21
TabOrder = 1
end
object Edit2: TEdit
Left = 120
Top = 184
Width = 121
Height = 21
TabOrder = 2
end
object Edit3: TEdit
Left = 240
Top = 184
Width = 177
Height = 21
TabOrder = 3
end
object Edit4: TEdit
Left = 416
Top = 184
Width = 121
Height = 21
TabOrder = 4
end
object Edit5: TEdit
Left = 536
Top = 184
Width = 121
Height = 21
TabOrder = 5
end
object Edit6: TEdit
Left = 656
Top = 184
Width = 121
Height = 21
TabOrder = 6
end
object Button1: TButton
Left = 0
Top = 208
Width = 777
Height = 25
Caption = 'Dodaj wpis'
TabOrder = 7
OnClick = Button1Click
end
object IBDatabase1: TIBDatabase
Connected = True
DatabaseName = 'H:\Documents and Settings\hawk\Pulpit\baza\ZNAJOMI.GDB'
Params.Strings = (
'user_name=sysdba'
'password=masterkey')
LoginPrompt = False
DefaultTransaction = IBTransaction1
IdleTimer = 0
SQLDialect = 1
TraceFlags = []
Left = 64
Top = 32
end
object DataSource1: TDataSource
DataSet = IBQuery1
Left = 216
Top = 32
end
object IBQuery1: TIBQuery
Database = IBDatabase1
Transaction = IBTransaction1
Active = True
BufferChunks = 1000
CachedUpdates = False
SQL.Strings = (
'Select * From znajomi')
Left = 136
Top = 32
end
object IBTransaction1: TIBTransaction
Active = True
DefaultDatabase = IBDatabase1
AutoStopAction = saNone
Left = 296
Top = 32
end
object PopupMenu1: TPopupMenu
Left = 168
Top = 256
object Usuwpis1: TMenuItem
Caption = 'Usu'#324' wpis'
OnClick = Usuwpis1Click
end
end
end
Treść pliku Project.dpr
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Aby program działał na waszych kompach musicie utworzyc te pliki, utworzyć bazę danych znajomi z tabelą znajomi, i ewentualnie zmienić właściwość DataBaseName dla komponentu IBDatabase1 bo ja mam H:\Documents and Settings\hawk\Pulpit\baza\ZNAJOMI.GDB - chyba że macie bazę danych w takiej samej lokalizacji jak ja
Mam problem.... wszystko gra oprócz tego że nie mogę dodać rekordu do tabeli... wyskakuje mi błąd SQL 206 nieznana kolumna... :( nie wiem co zrobić pomóżcie ....
Witam. Mam takie pytanko. Powiedzmy ze mam juz ten generator, ktory przechowuje wartosc id ostatniego rekordu.. jak ta wartosc przypisac do zmiennnej w delphi?
Witam! Czy ktos wie jak zrobic ta baze danych ale za pomoca dwoch tabel i ja powiazac, w jaki sposob?co trzeba zrobic. Lamerskie pytanie ale dopiero sie ucze tego:) z gory dziekuje
ID_znajomego najlepiej jest generować za pomocą generatora
w wyzwalaczu ( trigger before insert ) .
Chociaż nie koniecznie tam, bo można taki generator wyzwolić już w kodzie programu.
Ale załóżmy, że tworzymy to w wyzwalaczu.
Czyli musimy wykreować taki generator (np. za pomocą programu IBConsole lub innego) instrukcją
create generator gen_id_znajomego;
commit work;
Następnie musimy wykreować trigger (wyzwalacz).
Czyli ponownie za pomocą programu IbConsole lub innego
create trigger znajomi_bef_ins for znajomi active before insert position 0
as
begin
if ( (new.id_znajomego is null) or (new.id_znajomego = 0) ) then
new.id_znajomego = gen_id(gen_id_znajomego, 1);
end;
commit work;
Przed create trigger może trzeba będzie umieścić klauzulę zamieniającą
znak średnika na inny terminator
(na przykład ^)
set term ^;
Zależy to od programu i sposobu w jaki będzie kreowany trigger.
W takim przypadku cała instrukcja SQL będzie miała postać
set autoddl off;
set term ^;
create trigger znajomi_bef_ins for znajomi active before insert position 0
as
begin
if ( (new.id_znajomego is null) or (new.id_znajomego = 0) ) then
new.id_znajomego = gen_id(gen_id_znajomego, 1);
end^
commit work^
set term ;^
set autoddl on;
#max po to w IB są generatory i wyzwalacz, żeby takich szopek nie robić. A jak w tym samym momencie dwaj klieci zrobią SELECT MAX()...
to do staniesz dwa razy to samo ID
upss ..... korekta kodu ...
poz_temp:=pzapytanieSelect('SELECT MAX(ID) as ID FROM ZAMOWIENIA',F_ADDZAM.IBQUERY,F_ADDZAM.IBTRANZ,F_ADDZAM.IBDBA,'ID');
if Length(poz_temp)>0 then
begin
pozycja:=StrToInt(poz_temp);
Inc(pozycja);
end else
begin
pozycja:=1;
end;
Troche inna forma zabezpieczenia klucza z mojego programu co pisze eConvert Error niestety nie wszedzie działa jak trzeba
do var :
poz_temp: string;
pozycja: integer;
A teraz kod "żywcem" wziety z mojego softu, może komuś się przyda
poz_temp:=pzapytanieSelect('SELECT MAX(ID) as ID FROM ZAMOWIENIA',F_ADDZAM.IBQUERY,F_ADDZAM.IBTRANZ,F_ADDZAM.IBDBA,'ID');
if Length(poz_temp>0) then
begin
pozycja:=Inc(StrToInt(poz_temp));
end else
begin
pozycja:=1;
end;
zgadzam się z Bodkiem, i trochę moich uwag:
Jeśli torzysz jakiś artykuł to masz nadzieję, że ktoś z niego skożysta i będzie się na nim opierał podczas swoich początków, dlatego spoczywa na Tobie pewna odpowiedzialność ponieważ jeśli podasz złe wzorce to ktoś je od Ciebie przejmie. Po artykule widać, że sam nie do końca rozumiesz IB/FB oraz bazy danych jako takie. Temat jest tylko muśnięty i należało by z tego zrobić kilka odcinków poprzedzając je jakąś teorią.
To są moje wnioski, moim zamarem nie był obrażenie Cię ale wskazanie Ci drogi i pokazanie błędów, które jeszcze popełniasz.
Uwagi odnosnie artykulu:
Uwagi może subiektywne ale szczere (od roku programuję w OpenSource'owej kontynuacji Interbase - Firebird'zie)
Jak dla mnie całkiem całkiem, dopiero zaczynam w InterBas'ie i bazuje na tym artykule! dzieki:)
To nie jest komentarz, a raczej zapytanie czy jest w InterBase'ie takie cos jak AUTO_INCREMENT ?
Amras - jeśli w wersji Personal masz palety komponentów InterBase i Interbase Admin to na pewno będzie działać - a jeśli tych komponentów nie ma to trzeba radzić sobie inaczej... ja nie mam tej wersji Delphi to nie wiem jakie komponenty bazodanowe są w Personal - ale do Interbase da sie połączyć za pomocą dbExpress - może następny art napiszę o innych sposobach łączenia się z bazami:)
Proponuję, abyś napisał taki artykulik dla dbExpress :) Napewno byłby bardzo przydatny ~.^
a czy to działa na wszystkich wersjach Delphi 7?? Konkretnie sie pytam o wersje Personal.
Wg mnie artykulik pierwsza klasa....
_PiotR_ek - niestety nie ma takiego czegoś w InterBase jak auto_increment - ale można sobie z tym poradzić tworzac np procedurę składowaną albo organizując to za pomocą zapytań SQL - na pewno sam znajdziesz jakieś rozwiazanie:)