![]() |
Datenbank: Firebird • Version: 1.5 • Zugriff über: Zeos
Firebird Generator/Trigger für Autoinc (Verständnis_Problem)
Hallo,
ich beschäftige mich erst seit einigen Tagen richtig mit SQL-Datenbanken (FireBird via Zeos). Gerade bei Funktionen, die "innerhalb" der Datenbank ablaufen, hapert es bei mir noch arg mit Wissen und Verständnis. Ich hab' mir jetzt eine Funktion gebaut (via DP-Tutorial), die für eine Tabelle in einer FireBird-Datenbank ein AutoIncrement-Feld definiert. Das funktioniert auch soweit gut:
Delphi-Quellcode:
Bei meinem nächsten Übungsprojekt sollen jetzt mehrere Tabellen einer Datenbank ein Autoincrement-Feld bekommen. Da sind mir jetzt ein paar Fragen gekommen, mangels Wissen zu Generator/Trigger. Das Tutorial ist darauf, soweit ich es nicht übersehen habe, auch nicht eingegangen:
procedure FireBirdAutoInc(const zConnection: TZConnection; Table, forField : String);
var zQuery : TZQuery; Column : Integer; begin { TODO : Spalten-Nummer anhand Feldnahme ermitteln, statt der statischen 0 } Column := 0; zQuery := TZQuery.Create(Application); try with zQuery do begin // Verbindung festlegen und prüfen Connection := zConnection; if Assigned(Connection) and Connection.Connected then begin // Generator erzeugen SQL.Text := 'CREATE GENERATOR SetID_AUTOINC;'; ExecSQL; // Generator mit Spalte verbinden SQL.Text := 'SET GENERATOR SetID_AUTOINC TO '+IntToStr(Column); ExecSQL; // Trigger definieren SQL.Clear; SQL.Add('CREATE TRIGGER AUTOINC_TRG for '+Table); SQL.Add('active before insert position '+IntToStr(Column)); SQL.Add('as'); SQL.Add('begin'); SQL.Add(' new.'+forField+' = gen_id( SetID_AUTOINC, 1 );'); SQL.Add('end'); ExecSQL; end; end; finally zQuery.Free; end; end; "Generator" scheint Global zu sein, also nicht direkt an die Tabelle gebunden, andererseits aber an eine Spaltennummer.
|
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Dann ist meine Sequenz (Generator) SetID_AUTOINC eine globale Variable, die mit dem Code in Trigger hochgezählt und in das angegebene Feld eingefügt wird?
|
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Ja so könnte man es beschreiben
|
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Danke, das hat mich doch einen großen Schritt weitergebracht. Zumindest der Zusammenhang ist jetzt wesentlich klarer :-D
Da meine Tabellen einen eigenen Nummernkreis bekommen sollen, bekommt Generator je einen Namen, der den Tabellennamen mit drin hat: Tabelle_1_AutoInc, Tabelle_2_AutoInc etc. |
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Hier noch meine angepasste Funktion aus meinem Übungsprojekt. (fehlt noch etwas Sicherheit, aber denke erstmal sicher genug)
Legt für die angegebene Tabelle einer Firebird-Datenbank einen individuellen Generator (Sequenz) an. Wird dann von einer Trigger-Funktion als AutoIncrement für das angegebene Feld verwendet. (Hoffe soweit richtig formuliert) Das ganze wird nach 'CREATE TABLE...' aufgerufen und nimmt an, das pro Tabelle nur ein Autoincremet-Feld nötig ist.
Delphi-Quellcode:
Etwas unsicher bin ich nur noch, ob "zQuery.Connection.GetColumnNames" auch immer die richtige Reihenfolge der Spalten übergibt. Also ob die ermittelte "Column" sicher ist.
procedure FireBirdAutoInc(const zConnection: TZConnection; Table, forField : String);
var zQuery : TZQuery; Column : Integer; begin { TODO : Prüfen, ob bereits eine Sequenz/Generator mit ensprechendem Namen existiert Prüfen, ob erfolgreich } zQuery := TZQuery.Create(Application); try with zQuery do begin // Verbindung festlegen und prüfen Connection := zConnection; if Assigned(Connection) and Connection.Connected then begin // Generator erzeugen SQL.Text := 'CREATE GENERATOR '+Table+'_AUTOINC;'; ExecSQL; // Generator mit Spalte verbinden SQL.Text := 'SET GENERATOR '+Table+'_AUTOINC TO 0'; ExecSQL; // Trigger definieren SQL.Clear; SQL.Add('CREATE TRIGGER AUTOINC_TRG for '+Table); SQL.Add('active before insert position 0'; SQL.Add('as'); SQL.Add('begin'); SQL.Add(' new.'+forField+' = gen_id( '+Table+'_AUTOINC, 1 );'); SQL.Add('end'); ExecSQL; end; // if Assigned... end; // with zQuery do finally zQuery.Free; end; end; |
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Position ist aber nicht die Spaltennummer sondern regelt nur die Reihenfolge des Aufrufs der Trigger, wenn mehrere Trigger für das selbe Ereignis vorhanden sind. Du kannst dir also die Ermittlung der Spaltenposition sparen.
|
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Ok, ich scheide es oben wieder raus.
Ich merke schon, für eine größere SQL-Datenbank muss ich mehr lernen als erwartet. Zu Sequenzen, Transaktion und Funktionen lerne ich am besten erstmal mehr mit einem guten Buch. |
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
(Nachtrag: Datenbank: Firebird Embedded, Version: 2.1.2, Zugriff über: ZEOS 6.6.4 )
Hi, Ich wollte deine Funktion gerne verwenden, und habe mir daher folgendes Konstrukt gestrickt:
Delphi-Quellcode:
DoQuery ist einfach nur eine Funktion, die ein Query ausführt. Wenn ich das so mache, wie geschrieben, kommt diese Fehlermeldung:
DoQuery('CREATE TABLE MEMBERS (ID BIGINT NOT NULL, MEMBER_ID BIGINT,"TYPE" VARCHAR(255), REF BIGINT,"ROLE" VARCHAR(255));');
DoQuery('CREATE TABLE NODES (ID BIGINT NOT NULL, NODE_ID BIGINT, LAT FLOAT, LON FLOAT, TAGS VARCHAR(20000));'); DoQuery('CREATE TABLE RELATIONS (ID BIGINT NOT NULL, RELATION_ID BIGINT, MEMBERS VARCHAR(5000), TAGS VARCHAR(5000));'); DoQuery('CREATE TABLE TAGS (ID BIGINT NOT NULL, "KEY" VARCHAR(255), "VALUE" VARCHAR(255));'); DoQuery('CREATE TABLE WAYS (ID BIGINT NOT NULL, WAY_ID BIGINT, NODES VARCHAR(5000), TAGS VARCHAR(5000));'); FireBirdAutoInc(fConnection,'NODES','ID'); FireBirdAutoInc(fConnection,'TAGS','ID');
Code:
Was läuft da falsch? Liegt das an den identischen Spaltennamen? Eigentlich dürfte das doch kein Problem darstellen, oder? Wobei ich auch ehrlich zugeben muss, dass ich das mit den Generatoren und Triggern noch nicht komplett durchgeblickt habe... :stupid:
---------------------------
Benachrichtigung über Debugger-Exception --------------------------- Im Projekt saxxmltest.exe ist eine Exception der Klasse EZSQLException mit der Meldung 'SQL Error: unsuccessful metadata update DEFINE TRIGGER failed attempt to store duplicate value (visible to active transactions) in unique index "RDB$INDEX_8". Error Code: -607. This operation is not defined for system tables. The SQL: CREATE TRIGGER AUTOINC_TRG for TAGS active before insert position 0 as begin new.ID = gen_id( TAGS_AUTOINC, 1 ); end ; ' aufgetreten. --------------------------- Anhalten Fortsetzen Hilfe --------------------------- |
Re: Firebird Generator/Trigger für Autoinc (Verständnis_Prob
Wegen fehlendem Commit sind die Tabellen bei der Anlage der Trigger noch nicht sichtbar
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz