Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   FireDAC : Trigger geht nicht (https://www.delphipraxis.net/186469-firedac-trigger-geht-nicht.html)

Hansa 5. Sep 2015 12:35

AW: FireDAC : Trigger geht nicht
 
Zitat:

Zitat von IBExpert (Beitrag 1314826)
Wichtig: Nur weil Firebird und FireDAC vorne vier gleiche Buchstaben haben, ist FireDAC keineswegs die erste Wahl für Firebird und Delphi.

Ist wohl so und ich habe das vorher auch schon geahnt. Denn : wenn EINE Komponentensammlung mehrere Datenbanken unterstützt dann kann sie meiner Meinung nach nie für eine spezielle, hier also Firebird, optimal sein.

Aber egal. FireDac beschwert sich immer noch beim Einfügen eines unique Key-Felds. Offensichtlich wird immer nur auf den Titel geantwortet und nicht im Kontext. :shock: Ich werde das Problem deshalb jetzt reduzieren. Neue Datenbank anlegen mit einer Table und dann mal sehen. Da sich dadurch wohl nichts ändern wird, werde ich gegebenenfalls neues Thema aufmachen. Dürfte nicht lange dauern. :mrgreen:

Wenns endlich geht, befülle ich die DB mit FireDac dann mal neu. Das Daniel-Array und die Überlegungen von Holger Klemt werde ich dann eventuell auch einbauen. Mein Generator (es gibt nur einen) steht bei ca. 2.000.000. 10.000 Einfügeoperationen pro Sek. wär natürlich schon gut.

Frank Ingermann 5. Sep 2015 12:51

AW: FireDAC : Trigger geht nicht
 
Hallo Hansa,

wie schon gesagt: wenn Firebird meckert, dass es die Nr. 101 schon gibt, dann ist das so(!).

Wenn die Tabelle beim Start wirklich leer ist, dann kann das eig. nur daran liegen, dass
zwei Insert-Befehle mit der gleichen NR nacheinander abgesetzt werden. Am besten mal
in die MON$-Tabellen im Firebird schauen oder mit einem Trace-Tool (z.B. Thomas
Steinmaurer's Fb Tracemanager) nachsehen, was *wirklich* im Server ankommt.

Nur so kannst Du irgendwelche "behind the scene magic" in FireDAC ausschliessen.


Hi Holger,

( lange nicht gesehen :wink: )

ich stimme Dir in allen Punkten zu. Nur noch ein Hinweis dazu:

Wenn man mit der EXECUTE BLOCK-Methode arbeitet, sollte man trotzdem jeden Generatorwert per
"select gen_id..." aus der DB holen. Es kamen schon mal Leute auf die Idee, die IDs Client-seitig
hochzuzählen und anschließend mit SET GENERATOR den Generator in der DB auf den zuletzt
vergebenen Wert zu setzen, oder sich mit "select gen_id(genid,1000) from rdb$database"
mal eben 1000 Generatorwerte auf einen Schlag zu "reservieren".

Beides funktiniert aber nur, wenn man exklusiven Zugriff auf die DB hat - sobald mehrere
User oder Programminstanzen an der DB hängen, die das u.U. gleichzeitig machen können,
kann das furchtbar schiefgehen... immer dran denken, dass Generatoren außerhalb jeder
Transaktions-Kontrolle arbeiten! :thumb:

lg, Frank

IBExpert 5. Sep 2015 13:38

AW: FireDAC : Trigger geht nicht
 
Moin, Frank,

jo, volle Zustimmung, aber in der ID Spalte brauchst du ja auf dem Weg über execute block gar nichts eintragen und kannst die einfach weglassen, denn da greift ja ggf. der auf der Tabelle definierte Autoinc Trigger und eine Zugriffskomponente brauch sich da auch nicht einmischen.

Von einem früheren Projekt, wo der Kunde mit Informix gearbeitet hat, weiss ich noch von einem Bug, der erstmalig nach ca 9 Monaten Echtbetrieb aufgetaucht ist. Die Primärschlüssel und damit auch die Fremdschlüssel für Details wurden immer aus Nummernkreistabellen geholt. Dabei nutzte man ein Verfahren, was angeblich auch im Multiuserbetrieb mit Informix sicher war.

Dummerweise ist da nach 9 Monaten mal jemandem in der Logistik ein Lieferschein aufgefallen, auf dem keine Positionen waren. Der Mitarbeiter hat den also so abgearbeitet und eben nichts geliefert, den Lieferschein aber erst abends seinem Vorgesetzten vorgelegt. Dieser hat dann am Folgetag in der Fachabteilung nachgefragt, weil laut Auftragsbearbeitung sollte da auch was geliefert werden.

Ein wenig Recherche und schon stellte man fest, das die Positionen dummerweise auf einen anderen Lieferschein gebucht wurden, der für einen anderen Kunden war und schon ausgeliefert wurde. Auf Nachfrage bei dem Kunden hatte der sich dann auch schon gewundert, was da geliefert wurde, weil er dazu wiederum auch keine Bestellungen finden konnte.

Der Vorgang Lieferschein anlegen war ein Modul in der im Haus selbst programmierten Software und dort wurde dann einfach mal der Wert aus der Tabelle mit den Nummern ausgelesen, aber beim schreiben der Erhöhung um 1 war da der allseits beliebte try ... except {mir doch egal} end; drumherum, also im Falle einer Exception wird nix gemacht.

Da sich also wohl erstmals nach 9 Monaten Echtbetrieb zwei Buchungen in die Quere kamen, rächte sich diese Schlampigkeit. Da auch noch die Lieferscheinnummer als Fremschlüssel genommen wurde (und nicht ein rein technischer Wert wie zum Beispiel die von allen Firebird Programmierern bevorzugten Generatorwerte, die mit 64 Bit reichlich Platz bieten), wurden daher wohl die Detailbuchungen vom Client dem falschen Kopf zugeordnet. Oder mit anderen Worten, diverse Paletten wurden kreuz und quer durch die Gegend sinnlos hin- und zurück gefahren, weil ein Programmierer da ein ungeeignetes Verfahren gewählt hat. Im Nachhinein ist dann wohl jemandem noch aufgefallen, das wohl schon häufiger vorkam, aber wohl bisher noch nie ein komplett leerer Lieferschein erzeugt wurde.

Wie ich und Frank und viele andere sicher auch bestätigen können, ist der Weg über den Trigger und Gen_id() bzw. direkt über Gen_id() der einzig richtige Weg für Firebird, um netzwerksicher und transaktionssicher bei der Primärschlüsselerzeugung zu sein. Ich für meinen Teil benutz dabei dann auch noch einen einzigen Generator für alle Tabellen, was diverse weitere Vorteile hat.

Da es diese Konstrukte aber bei anderen Datenbanksystemen nicht gibt, muss eine Komponentenbliothek wie FireDAC dann eben auch unter Berücksichtigung der TDataset Kompatibilität da diverse Kompromisse und Workarounds machen.

Ich für meinen Teil arbeite mit TDatasets im Insert/Edit/append/post Verfahren schon seit 10 bis 15 Jahren nicht mehr freiwillig (ist aber von der Höhe des Honorars abhängig), weil ich der Datenbank in SQL Sprache sage, was ich von der will und Datasets nur zum Lesen für select Ergebnisse benutze.

Daniel 5. Sep 2015 14:04

AW: FireDAC : Trigger geht nicht
 
Moin,

was FireDAC da macht, ist weder ein Kompromiss noch ein Workaround. Entweder verbindest Du das PK-Feld mit dem Generator und hast den Wert dann schon direkt nach dem Append/Insert, sofern Du ihn da benötigst oder Du stellst die Komponente so ein, dass Du das PK-Feld leer absenden kannst.
In jedem Fall wird der Entwickler gezwungen, sich mit der Frage zu befassen, damit z.B. solche wie von Holger geschilderten Fehler nicht passieren.

haentschman 5. Sep 2015 15:05

AW: FireDAC : Trigger geht nicht
 
Hallo Hansa...:roll:

probiere doch einfach mal die einfache Query. Da wirst du sehen das das funktioniert. Das Problem liegt zu 99.99% wie schon mehrfach gesagt an den Einstellungen der Table die du verwendest und nicht am eigentlichen Trigger der DB. Für das Layer 8 Problem gleich die Komponenten madig zu machen ist nicht nett. :P

Hansa 6. Sep 2015 14:19

AW: FireDAC : Trigger geht nicht
 
Moin,

ich habe doch nicht rumgemosert. Lediglich angemerkt, dass manche Sachen nicht da sind, wo man sie erwarten würde und vom Namen her auch der Zweck nicht direkt erkennbar ist. Deshalb ist manches schlecht zu finden. Nachdem Dank Daniel klar war, warum die ID Ärger macht, dann aber ging, hatte ich mir nochmals die Update-Options angesehen, weil der unique Key ja auch anfangs nicht ging. Und siehe da, da gibts KeyFields. Was das bei UpdateOptions zu suchen hat, obwohl das ja auch nur zum Lesen gebraucht wird, führt einen in die Irre. Immerhin : das Wort Key ist auch im "unique Key" zu finden. Da habe ich dann das Feld NR eingetragen und dann ging auch das.

Ich habe also grob geschätzt ca. 6 St. gebraucht für :

Komplette neue DB anlegen, samt Triggern und Keys mit IBExpert. Da mir ja nicht geglaubt wurde, dass der Trigger auf DB Seite geht bzw. das einfach überlesen/ignoriert wurde, habe ich unnötig viel Zeit in die Überprüfung des Triggers investiert.

In Delphi habe ich dann noch Datamodul mit dem FireDAC Zeugs angelegt und das alles soweit richtig eingestellt. Viel lesen in der Hilfe kam noch dazu und jetzt kommt noch noch etwas zum meckern :

Aber eher an Emba : nicht nur bei den Update Options sagt mir die Hilfe folgendes :

Code:
Embarcadero Technologies verfügt zurzeit über keine zusätzlichen Informationen. Bitte unterstützen Sie uns bei der Dokumentation dieses Themas, indem Sie Ihre Kommentare auf der Diskussionsseite eingeben.
Man muss aber mehr fragen/suchen als unbedingt nötig.

Das eigtliche Delphi-Testprogramm habe ich ja auch noch gemacht und getestet. Jedenfalls bin ich mit sechs St. Aufwand zufrieden. Jemand, der sich weniger auskennt, der hätte wohl eher 6 Tage gebraucht und ein blutiger Anfänger sogar 6 Wochen.

mkinzler 6. Sep 2015 14:25

AW: FireDAC : Trigger geht nicht
 
Und hättest Du jetzt noch den Debugger und den SQL-Monitor verwendet ...

Hansa 6. Sep 2015 15:06

AW: FireDAC : Trigger geht nicht
 
Für FireDAC oder was ?

mkinzler 6. Sep 2015 15:06

AW: FireDAC : Trigger geht nicht
 
Ja.

Daniel 6. Sep 2015 18:05

AW: FireDAC : Trigger geht nicht
 
Ab und an muss man ein wenig klicken, aber hier sind die Optionen allesamt aufgelistet:
http://docwiki.embarcadero.com/Libra...ons_Properties


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:40 Uhr.
Seite 4 von 5   « Erste     234 5      

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