![]() |
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:
geführt.
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
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!! |
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.
|
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. :( |
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. |
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 |
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. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
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? |
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:
Aufbau der Tabelle1:
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 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 |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
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>). |
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: ![]() 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. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Hallo, danke für die Antwort, es gibt aber wirklich zu 100 % keine Stelle im Hauptprogramm und auch kein weiteres Programm welches abgesehen von den Triggern auf den Generator zugreift oder Werte in die Tabelle schreibt, ich hab sicherheitshalber noch einmal den ganzen Sourcecode geprüft. Es ist wirklich ausschließlich der Trigger - nach einem Backup und Restore läuft es auch wieder, allerdings tritt das Problem immer wieder und an verschiedenen stellen ( wie am Anfang erwähnt auf mit anderen Generatoren ) auf :( es ist zum Mäuse melken
|
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Hallo,
wie Lemmy geschrieben hatte, musst Du bei RollBacks aufpassen. Meines Wissens laufen die Generatoren ausserhalb der Rollbacks. siehe auch hier: ![]() Komisch ist, dass er auf einem alten Wert steht. Laut dem Generatorguide hätte ich eher Lücken in der Sequenz erwartet. Zitat:
Du hattest geschrieben, dass du nichts vergleichbares gefunden hattest. Vielleicht ja so was ? ![]() Wie viele Insert-Statements in die Archiv-Tabelle hast Du in deinem Code? |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Verstehe ich das jetzt richtig:
Der Generator gibt bei Abfrage z. B. den Wert 100 aus, obwohl er eigentlich schon bei 105 sein sollte. Nun machst Du ein Backup und ein Restore und fragst dann den Generator erneut ab und er enthält dann den erwarteten Wert von 105? Das sieht dann aber eher nach einem Datenbankproblem aus. Gibt es da irgendwo einen Bug? Wie hoika schreibt, darf bei der Vergabe der ID eine Lücke entstehen, wenn ein Rollback gemacht wird, aber das ein Generator auf einem alten, bereits vergebenen, Wert steht, widerspricht der Spezifikation. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Sorry ich schreib das hier nebenher...
nochmal ausführlich vielleicht: Es gibt keinen Insert auf die Archiv Tabelle im Code - Ausschließlich über den Trigger auf der Tabelle selbst. Für eine unvorhersehbare Zeit funktioniert alles prima, plötzlich steht der Generator auf einem alten Wert. Übersprungene Werte habe ich noch nicht gesehen, sind aber auch kein Problem. Wenn ich den Generatorwert nun händisch korrigiere funktioniert es 1 mal, danach ist der Wert wieder falsch. -- Bei anderen Fällen ging es dann aber auch wieder für längere Zeit Wenn ich vor oder nach der Korrektur ein Backup Restore durchführe tritt der Fehler nicht mehr auf ( zumindest für eine gewisse Zeit ) Der Generator wird Ausschließlich im Trigger angesprochen Das selbe tritt auch bei anderen Tabellen auf, welche nur zum Teil durch den Trigger mit der ID versehen werden, ab und an wird der Generator auch direkt angesprochen ( daher die Abfrage auf ID is null) Das ganze passiert in einigen Kopien der Datenbank, aber nicht in allen. Es passiert zu unterschiedlichen Aktionen Zeiten und bei unterschiedlichen Generatoren - ich konnte bisher noch keine Gemeinsamkeit entdecken. Es gibt für den aktuellen Fall kein Element abgesehen von den Triggern welches auf Generator oder Tabelle Archiv zugreift Danke nochmal für eure Mühen |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
|
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Hallo,
vielleicht wird ja in einem Trigger, der nicht so häufig verwendet wird, der falsche Generatorwert drin. Exportiere mal deine DB (IBExpert, ExtractMetaData) und suche dort nach Deinem Generatorwert. Was hat Deine DB für eine Endung, FDB oder GDB (Stichwort Schattenkopien)? |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
ok, danke! werde ich versuchen!
|
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
|
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
Sind die zitierten Aussagen oben nicht widersprüchlich? Und, es ist vollkommen wurscht, ob der Generator nebenher angesprochen wird. Entscheidend ist, woher die Werte kommen, die in der Tabelle landen. Oder anders: Du kannst dem Generator soviel Werte aus dem Kreuz leiern, wie Du magst. Und mit denen kannst Du machen, was Du willst. Wichtig ist nur, dass in einer Tabelle die ID aus genau einem Generator kommt und in Deinem Fall sicherheitshalber bedingungslos, also ohne irgendwelche Prüfungen. Es ist nicht ungewöhnlich, einen Generator als unique Quelle für mehrere oder auch viele Tabellen zu verwenden. Es gibt sogar Dinge, die dafür sprechen. Das gilt unabhängig von Deinem spezifischen Problem hier, die Reparatur bzw. Prüfung der DB Konsistenz würde ich als erstes machen und vor allem versuchen die Ursache zu finden. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
wie überprüfst Du, daß der wert des Generators korrekt ist?
Wenn Du schreibst: Zitat:
Ggf. wäre es günstig uns mal die Statements zu zeigen bei denen der Fehler auftritt. Gruß K-H |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Hallo,
FDB als Endung ist schon mal gut, dann fällt mein Hinweis mit den Schattenkopien schon mal weg. Welche genaue Version von Firebird hast Du? Solche Fehler sind dann leider schwer zu finden. Du musst versuchen, das zu reproduzieren. Schreib Dir ein Extra-Programm, was Deine DB mit typischen Anfragen bombardiert und versuche somit, den Fehler nachzustellen. Wenn Dein Programm im Netzwerk läuft, dann starte es doppelt oder besser auf 2 Rechnern oder 2 VMs. Ich hatte mal vor 'zig Jahren so einen Fall mit einer Paradox-DB beim Kunden (jaja, gab es damals;)). "Index out of date", puh. Ich hatte sogar einen gleichen (Windows-)Server aufgebaut, das Bombardier-Test-Programm auf 2 Rechnern gestartet, und konnte diesen Fehler nicht nachstellen. Mit der Umstellung auf IB/FB war das dann aber gelöst ;) |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
|
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
und ich kann versichern, dass die statements absolut ok sind müsste aber jeden tabellen und feldnamen uws. ändern um sie hier einzustellen. darum geht es aber auch garnicht. das problem ist der generator der hängen bleibt - bei der selben anweisung bei der der vorher unbestimmte male problemlos funktioniert hat Zur Frage wie ich den wert prüfen: da wie bereits erwähnt die id für tabelle1_archiv ausschließlich über den generator vergeben wird muss ich nur den generatorwert mit max id abgleichen. ist max id größer ( was in dem fall zutrifft ) ist natürlich der generator falsch - die id kann ja von nirgendwo sonst herkommen.... |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
Der Trigger erlaubt ohne weiteres die manuelle Vergabe eine beliebigen ID, von sich aus größer oder kleiner als der aktuelle Generatorstand. Die Formulierung im Triggercode erlaubt das "Überschreiben" des Generatorwertes, genauer der Trigger unterbindet seine Tätigkeit freiwillig, wenn er bereits einen Wert vorfindet. Der Triger bzw. das Gesamtkonstrukt ist also nicht wasserdicht! In der Praxis wird das "kleiner" nur selten oder fast nie oder nie eintreffen, wenn alle Werte kleiner als der aktuelle Generatorwert bündig vergeben wurden und demzufolge eine Schlüsselverletzung eintritt, wenn "blind" eine ID kleiner als Generator eingefügt wird. Jemand der also manuell einen Datensatz eintragen will, fragt entweder selber gleich den Generator ab oder max(id) oder stochert solange, bis der geratene Wert größer als der Generator ist. Dann ergibt Deine Prüfung ein falsch, max(id) ist dann kleiner als der Genererator. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
das mit dem reproduzieren kann ich auf jeden fall mal versuchen |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Zitat:
Das liegt daran, dass die tabelle1_archiv ( das gilt nur für diese tabelle, hier tritt das problem auch, nicht ausschliesslich, auf) wirklich ausschliesslich über die 3 trigger auf der tabelle1 angesprochen wird in welchen der wert ID nicht vorkommt. |
AW: Firebird 2.5 Generator falsch - Trigger FireDAC
Ja ach, das kannst Du meinetwegen so sehen und auch darauf beharren.
Ich spar mir jetzt eine Aufzählung von hypothetischen Möglichkeiten, die eingetreten sein können, Murphy's Law usw., die Deine Aussage zunichte machen können. Ich stelle nur ein paar Fragen und liefere Hinweise, denn ich sehe das so: Datenbanken sind dafür da, die Einhaltung bestimmter Regeln zu erzwingen. Genau dafür sind sie gemacht, das ist im Zweifel ihr Erfolgsrezept. ACID konforme Datenbanken machen das nicht einfach irgendwie, sondern sie garantieren(!) es. Die Logik "kann nicht sein, weil wäre zwar möglich, kommt aber nicht vor" (die streng genommen nicht logisch ist), ist eine vollkommen unnötige. Die Logik oder ihre Aussage wird auch nicht besser, wenn man dazu auf die Bibel schwört. Jedes "Loch" was ich stopfen kann, stopfe ich, spätestens wenn Probleme auftreten, die sich mit der lachsen Handhabung in Verbindung bringen lassen. Warum soll ich mir das Leben schwer machen mit "hätte, hätte Fahrradkette"? Was du schilderst, wäre ohne gefundene Erklärung und mit erwiesener Reproduzierbarkeit ein handfester Bug. Meine Erfahrung ist, dass es besonders auf diesem grundsätzlichen Niveau solche Bugs viel seltener gibt, als sie herbeigerufen werden. Das zeigt sich idR. bei hinreichend gründlicher Prüfung. Dazu gehört der absolute Ausschluss aller "variablen" Faktoren, z.B. dieser Trigger. Was Du letztlich mit den Informationen hier im Thread machst, ist natürlich Deine Sache. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:50 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