Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird 2.5 Generator falsch - Trigger FireDAC (https://www.delphipraxis.net/195145-firebird-2-5-generator-falsch-trigger-firedac.html)

Emwykey 6. Feb 2018 09:36

Datenbank: Firebird • Version: 2.5 • Zugriff über: FireDAC

Firebird 2.5 Generator falsch - Trigger FireDAC
 
Hallo zusammen,

ich habe seit längerem das Problem, dass Generatoren auf unerklärlichen Wegen plötzlich die falschen Werte enthalten.
Besonders kurios ist folgender Fall:

in Tabelle1 werden über Trigger ( Before Insert, Before Delete und Before Update ) alte Daten in die Tabelle1_Archiv übernommen.
Die ID der Tabelle1_Archiv wird über einen Trigger ( Before Insert )
Code:
CREATE TRIGGER TABELLE1_ARCHIV_BI FOR TABELLE1_ARCHIV BEFORE INSERT POSITION 0 As Begin  If (New.ID is null) then New.ID = Gen_ID(ID_GEN_Tabelle1_Archiv, 1 ); end
geführt.
Die Tabelle Tabelle1_Archiv wird nie manuell angesprochen. Der zugehörige Generator ebenso nicht.
Es gibt keine Bedingung für den Log, er wird immer durchgeführt sobald Tabelle1 bearbeitet wird.

Denoch passiert es, dass von jetzt auf nachher der Wert des Generators zur Tabelle1_Archiv nicht mehr stimmt und somit natürlich auch das Insert/Update/Delete auf Tabelle1 fehlschlägt.

Woran könnte das liegen?
Danke im Voraus!!

Frickler 6. Feb 2018 10:19

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Ich würde bei dem Trigger testen auf "New.ID is null or New.ID = 0". Denn wenn der Feldwert irgendwo mit initialisiert wird, dann macht dein Trigger gar nichts.

Emwykey 6. Feb 2018 10:51

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Hallo, der Wert wird nicht initialisiert.. es funktioniert auch in 99% aller Fälle und ohne dass sich an den Befehlen, an der Datenbank, am Programm oder an dem Datenbankserver was ändert funktioniert es nicht mehr. Wenn ich den Generator Wert händisch korrigiere läuft es wieder.
Der Trigger liefert auch immer einen Wert zurück, aber den falschen, weil der Generator plötzlich den falschen Wert beinhaltet. Die Funktion GEN_ID wird abgesprochen, auch fehlerhafte Abfragen setzten den Wert hoch, nur stimmt er plötzlich nicht mehr.

Von jetzt auf nachher wird der Wert verfälscht, ohne, dass auf den Generator anderweitig zugegriffen wird. :(

jobo 6. Feb 2018 11:01

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Was bedeutet denn "..stimmt er nicht mehr.." konkret?
Ein Generator liefert gemäß Vorgabe eindeutige Werte in einem bestimmten Range. Macht er das nicht?
Und wie Frickler schon angemerkt hat:
Die Konstruktion des Triggers deutet darauf hin, dass das System darauf ausgelegt ist, Werte zu akzeptieren, die nicht vom Generator stammen.
Wenn Du nun sagst, das passiert in der Realität sowieso nicht, dann tu Dir doch den Gefallen, den Trigger auch so zu schreiben, dass das garantiert ist. Ein garantiertes Systemverhalten will man ja normalerweise erreichen.

Delphi.Narium 6. Feb 2018 11:13

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Wenn ID nicht initialisiert wird, dann ist die IS Null-Abfrage (mit Verlaub) unsinnig.

Soll eine ID vergeben werden?

Wenn ja, sollte man das auch tun und die Vergabe nicht von einer Bedingung abhängig machen, auf die man keinen Einfluss hat bzw. die, wenn sie doch mal zutreffen sollte, kontraproduktiv ist.

Das wäre dann so höchstwahrscheinlich sinnvoller:
SQL-Code:
CREATE TRIGGER TABELLE1_ARCHIV_BI FOR TABELLE1_ARCHIV BEFORE INSERT POSITION 0 As Begin
  New.ID = Gen_ID(ID_GEN_Tabelle1_Archiv, 1);
end

Emwykey 6. Feb 2018 11:14

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Hallo,

Der Generator scheint auf einen früheren Wert zurückzuspringen bei einer oder mehren Aktionen
Wenn ich zB die ID 100 vergeben habe und dann versuche die 101 zu vergeben stehen diese in der Tabelle richtig drin. Bei 102 ( es wird jede ID in dieser Tabelle ausschließlich über den Trigger generiert, es gibt auch Tabellen, da wird er Generator angesprochen ohne Trigger --> daher die Abfrage ( die Trigger sind alle identisch angelegt)) kommt es zu einem Fehler, da der Generator 101 zurück gibt. Es sieht also so aus, als ob er zurückspringen würde?????? da sonst die anderen IDs nie hätten erzeugt werden können.

Daher kann es nicht an der Abfrage im Trigger liegen, selbst wenn der Generator nicht angesprochen werden würde dürfte keine höhere ID in der Tabelle stehen. Das ist im Programm absolut unmöglich. Es scheint einen Moment zu geben, an welchem die Funktion GEN_ID den korrekten Wert liefert, aber der Generator nicht mehr erhöht wird. Ich hatte sogar schon den Fall, dass die Werte um mehrere IDs auseinander lagen.


Sicherlich ist das richtig, dass es besser wäre 0 mit zu prüfen, hat aber leider mit dem Fehler nichts zu tun.

Lemmy 6. Feb 2018 11:20

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Zitat:

Zitat von Emwykey (Beitrag 1393189)
Sicherlich ist das richtig, dass es besser wäre 0 mit zu prüfen, hat aber leider mit dem Fehler nichts zu tun.

Nö. Is Null ist an der Stelle korrekt, da ID=0 ein valider Wert ist.


Wie schaut denn dein Insert-Befehl an der Stelle aus (oder hast Du mehrere)? Du schreibst, dass die Tabelle ein "Archiv" ist, d.h. du schiebst da von einer Tabelle bestehende Datensätze da rein. Wird die ID von der bestehenden Tabelle auch in die neue Tabelle übernommen?

Emwykey 6. Feb 2018 11:29

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
ja, wird übernommen, allerdings in ein anderes feld, da insert update und delete geloggt werden.
Hier ein Beispiel ( Trigger auf TAbelle1 ):
Code:
CREATE TRIGGER TRIG_TABELLE1_LOG_BD FOR Tabelle1 BEFORE DELETE POSITION 0 as begin

Insert Into Tabelle1_Archiv (
Zeitstempel, Daten1, Daten2, ID_Tabelle1
) values ( Old.Zeitstemple, Old.Daten1, Old.Daten2, Old.ID ); end
Aufbau der Tabelle1:
ID | Zeitstemple | Daten1 | Daten2

Aufbau der Tabelle1_Archiv

ID | Zeitstemple | Daten1 | Daten2 | Tabelle1_ID

Before Insert ist natürlich mit NEW angegeben


ID 0 wird im System nicht verwendet, darf also nicht vorkommen :) , auch wenn es technisch natürlich ein gültiger Wert ist

Lemmy 6. Feb 2018 11:48

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Zitat:

Zitat von Emwykey (Beitrag 1393191)

ID 0 wird im System nicht verwendet, darf also nicht vorkommen :) , auch wenn es technisch natürlich ein gültiger Wert ist

echt? schon mal geschaut, was ein Trigger bei gen_ID(x,1) macht, der seinen maximalen Wert erreicht hat (9.223.372.036.854.775.807)?


die einfachste Lösung ist, dass Du die falschen Werte per Insert oder Update in die Tabelle schreibst. Das scheint nicht der Fall zu sein (obwohl ich nicht weiß was du in den Tiefen deiner SOftware so treibst :-))

Weiter ist denkbar, dass Du den Generatorwert der Archivtabelle manuell änderst (z.B. nach einem Rollback). Einen Updatetrigger gibt es nicht für die Archivtabelle?

Testest Du gerade an einer Produktivdatenbank? Zur Sicherheit (obwohl ich nicht denke, dass das die Ursache ist), check Deine Datenbank mal mit gfix (gfix -v -full -u sysdba -p <password> <Datenbankdatei>).

Delphi.Narium 6. Feb 2018 11:59

AW: Firebird 2.5 Generator falsch - Trigger FireDAC
 
Wenn dem so ist, wie oben beschrieben, wäre die Prüfung im Trigger zu ändern.

Wenn new.id is null oder new.id = 0 wird ein Wert vom Generator geholt, in jedem anderen Fall wird ein Fehler ausgelöst, um darüber festzustellen, wer da ggfls. was liefert. Ausgehend von Deiner Beschreibung dürfte dies eigentlich nie passieren (aber man weiß ja nie ;-))

Zuerst muss sichergestellt werden, dass von keiner Stelle eine ID in die Tabelle geschrieben wird, außer vom Trigger unter Zuhilfenahme des Generators.

Ein bisserl Info zum Thema: http://www.ibexpert.net/ibe_de/index...orenGrundlagen

Eventuell hilft dies bei der Fehlersuche. Der Fehler muss nicht zwingend in der Datenbank liegen, eventuell verhält sich irgendwo in einem Programm etwas nicht so, wie es eigentlich von der Systemarchitektur vorgesehen ist.

Z. B.:
Gibt es irgendwo ein Programm, das bei 'nem Rollback meint, den Generator zurücksetzen zu müssen.
Oder holt sich irgendwo jemand 'nen Wert vom Generator und zählt dann selbst weiter und schreibt in die Tabelle, so dass der Generator dadurch quasi "überholt" wird?

Prinzipell scheint es mir (mit den bisherigen Informationen) so, dass man auch mal alles außerhalb der Datenbank, was irgendwie mit den Tabellen zu tun hat (oder haben könnte), überprüfen müsste. Wird irgendwo auf den Generator zugegriffen, außer vom Trigger aus?

Habe leider keine Stelle gefunden, an der ein ähnlicher Fehler beschrieben wird, um festzustellen, ob es eventuell ein bekanntes Datenbankproblem sein könnte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 Uhr.
Seite 1 von 3  1 23      

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