AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Verwenden von Triggern für Firebird 2.5 DB
Thema durchsuchen
Ansicht
Themen-Optionen

Verwenden von Triggern für Firebird 2.5 DB

Offene Frage von "hoika"
Ein Thema von Frankdarwin · begonnen am 13. Apr 2011 · letzter Beitrag vom 15. Apr 2011
Antwort Antwort
Frankdarwin

Registriert seit: 27. Jan 2011
8 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Verwenden von Triggern für Firebird 2.5 DB

  Alt 13. Apr 2011, 14:17
Datenbank: Firebird • Version: 2.5 • Zugriff über: Interbase
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.
Frank
"Geht nicht, gibt's nicht!"
Schon gar nicht, bevor man es nicht porobiert hat.
  Mit Zitat antworten Zitat
ThomasBab

Registriert seit: 7. Mai 2007
Ort: Hallenberg
57 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Verwenden von Triggern für Firebird 2.5 DB

  Alt 13. Apr 2011, 14:40
Hallo!

Bin zwar kein Spezialist, aber vielleicht kann ich ein wenig Licht ins Dunkle bringen:

Hier ein praktisches Beispiel (Auszugsweise):

Die Tabelle:
Code:
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 ; ^
Hier der Generator:

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;
Thomas

Geändert von ThomasBab (13. Apr 2011 um 14:54 Uhr) Grund: Tabellendefinition war unvollständig
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Verwenden von Triggern für Firebird 2.5 DB

  Alt 13. Apr 2011, 14:49
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
Frank Reim

Geändert von dataspider (13. Apr 2011 um 14:55 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.297 Beiträge
 
Delphi 12 Athens
 
#4

AW: Verwenden von Triggern für Firebird 2.5 DB

  Alt 13. Apr 2011, 18:55
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

  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Verwenden von Triggern für Firebird 2.5 DB

  Alt 15. Apr 2011, 07:23
Hallo,

Zitat:
Was muss ich eigentlich in Delphi tun, damit ein Trigger aus der DB automatisch ausgeführt wird?
Die kurze Antwort ... Nichts.

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
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz