![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: Interbase
Verwenden von Triggern für Firebird 2.5 DB
Hallo Spezialisten,
ich versuche gerade meine ertsen Erfolgserlebnisse mit einer DB Anwendung zu bekommen. Zu diesem Zweck habe ich mit IBExpert eine einfache FB DB erstellt. Die Tabellen enthalteen alle ein Feld namens ID für den PK. Darüber hinaus habe ich einen Trigger erstellt, der das Feld ID versorgen soll. Das funktioniert unter IBE einwandfrei. Jetzt möchte ich um diese DB herum mit Delphi XE eine Anwendung zur Datenerfassung schreiben. Ich kann Daten in allen Feldern und Tabellen erfassen. Nur bekomme ich jedesmal eine Meldung, dass das Feld ID einen Wert benötigt. Eigentlich sollte dieser von dem Trigger eingetragen werden. Jetzt kommt meine (für viele wahrscheinlich sehr einfache) Frage: Was muss ich eigentlich in Delphi tun, damit ein Trigger aus der DB automatisch ausgeführt wird? Ich habe sehr viel gesucht und gelesen. Auch in den Foren. Viele Themen behandeln das Thema Trigger. Leider wurde ich zu meiner Grundsatzfrage nicht fündig. Oder ich habe es einfach überlesen. Ich würde mich über einen kleinen Nachhilfeunterricht in Form einer (oder mehrere) Antworten sehr freuen. |
AW: Verwenden von Triggern für Firebird 2.5 DB
Hallo!
Bin zwar kein Spezialist, aber vielleicht kann ich ein wenig Licht ins Dunkle bringen: Hier ein praktisches Beispiel (Auszugsweise): Die Tabelle:
Code:
Hier der Generator:
CREATE GENERATOR ID;
CREATE TABLE IPCAM ( ID BIGINT NOT NULL, IDCAM BIGINT NOT NULL, ANGELEGT DATUMUHRZEIT DEFAULT current_timestamp /* DATUMUHRZEIT = TIMESTAMP */ NOT NULL /* DATUMUHRZEIT = TIMESTAMP */, BILD BLOB SUB_TYPE 0 SEGMENT SIZE 16384 ); /******************************************************************************/ /* Primary Keys */ /******************************************************************************/ ALTER TABLE IPCAM ADD CONSTRAINT PK_IPCAM PRIMARY KEY (ID); /******************************************************************************/ /* Foreign Keys */ /******************************************************************************/ ALTER TABLE IPCAM ADD CONSTRAINT FK_IPCAM_1 FOREIGN KEY (IDCAM) REFERENCES CAMTYP (ID); /******************************************************************************/ /* Indices */ /******************************************************************************/ CREATE INDEX IPCAM_IDX1 ON IPCAM (ANGELEGT); /******************************************************************************/ /* Triggers */ /******************************************************************************/ SET TERM ^ ; /******************************************************************************/ /* Triggers for tables */ /******************************************************************************/ /* Trigger: IPCAM_BIU0 */ CREATE OR ALTER TRIGGER IPCAM_BIU0 FOR IPCAM ACTIVE BEFORE INSERT OR UPDATE POSITION 0 AS begin if (new.id is null) then new.id = gen_id(id, 1); if (new.angelegt is null) then new.angelegt = current_timestamp; end ^ SET TERM ; ^
Code:
CREATE SEQUENCE ID;
ALTER SEQUENCE ID RESTART WITH 619995; Nun der Codeauszug, um Daten einzutragen bzw. ein Update auszuführen:
Delphi-Quellcode:
procedure Tccamera.Speichercamtyp;
var Sql: string; begin try if CamTypName = '' then begin ShowMessage('Kein Kameratyp angegeben!'); exit; end; if CamTypID <= 0 then begin sql := 'insert into ' + Ftabtyp + ' (camname,adresse) values(:camname,:adresse);'; dm.tTypen.StartTransaction; dm.qTypen.SQL.Text := sql; dm.qTypen.Params.ByNameAsString['camname'] := UTF8Decode(CamTypName); dm.qTypen.Params.ByNameAsString['adresse'] := UTF8Decode(CamTypAdresse); end else begin sql := 'update ' + Ftabtyp + ' set camname=:camname, adresse=:adresse where id=:id;'; dm.tTypen.StartTransaction; dm.qTypen.SQL.Text := sql; dm.qTypen.Params.ByNameAsString['camname'] := UTF8Decode(CamTypName); dm.qTypen.Params.ByNameAsString['adresse'] := UTF8Decode(CamTypAdresse); dm.qTypen.Params.ByNameAsInt64['id'] := CamTypID; end; dm.qTypen.Execute; dm.tTypen.Commit; except on E: Exception do begin dm.tTypen.RollBack; ShowMessage(E.Message); end; end; end; |
AW: Verwenden von Triggern für Firebird 2.5 DB
Hi,
an dieser Stelle bleiben doch einige hängen. Der Hintergrund: Deine Datenmenge in deinem DataSet füllst du ja mit Daten. Dann erfolgt ein Insert und dein Dataset schickt eine Insert - Statement an die DB. Dein DataSet kennt alle Daten, die du eingegeben hast. Um auch die Daten zu kennen, die durch Trigger generiert werden, muss das DataSet dazu veranlasst werden, nach einem Insert quasi eine Syncronisation mit dem Server durchzuführen. Je nach Komponentenherstelle wir dieses Problem unterschiedlich angegangen. Die meisten erlauben es, den Generator und das KeyField anzugeben und holen den Wert für die ID selbst. Deshalb macht es Sinn, im Trigger immer ...if new.id is null then... zu verwenden. Such mal nach einer Eigenschaft GeneratorName und KeyFieldName. [EDIT] Für andere durch Trigger generierte Werte gibt es z.B. IBO: BufferSyncroFlags oder InvalidateRecord IBDac: RefreshOptions ... [/EDIT] Frank |
AW: Verwenden von Triggern für Firebird 2.5 DB
Hallo...
2 Dinge gibt es zu beachten: - wenn du den Trigger für eine automatisch hochzuzählende ID benutzt brauchst du einen Generator dazu. Dieser Generator stellt die ID zur Verfügung die dann in das entsprechende Feld eingetragen wird. Der Name des Generators ist frei wählbar und die Beispiele sind entsprechend anzupassen. - der Trigger BeforeInsert muß mit dem entsprechenden Code gefüllt sein. Wenn du einen Datensatz einfügst wird in der Regel die "erzeugte" ID nicht benötigt. Sie ist einfach eingetragen. In Ausnahmefällen braucht man die gerade eingetragene ID um evt. andere Datensätze mit dieser ID zu verknüpfen. Dafür gibt es bei FB returning :hi: |
AW: Verwenden von Triggern für Firebird 2.5 DB
Hallo,
Zitat:
Du übergibst als ID einfach 0, den Rest macht die DB. Die Meldung "muss Wert enthalten" kommt von deiner Datenzugriffs-Schicht (also lokal). Sie hat erkennt, dass das Feld "not null" ist, und will einen Wert haben. Welcher das ist, ist ihr egal, der Trigger erzeugt ja eh einen anderen. Die Sache mit dem Generator hast du ja wohl schon gemacht ? Ohne etwas von deiner DB hier zu sehen, ist das geraten. Unter IBExpert kannst du per Extract Metadata ja mal deine DB hier zeigen. Unter IBPhoenix.com findest du auch Beispiele dazu. Den erzeugten Wert Trigger-wert bekommst du über returning (wie schon weiter oben gesagt). Ohne das returning müsstest du den Generator selber auslesen (gen_id). Das ist aber bei FB 2.5 nicht mhr notwendig. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:29 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