Autor |
Beitrag |
jo-freaky
      
Beiträge: 24
|
Verfasst: Mi 28.06.06 17:22
Hi ihr,
hab' zur Abwechslung mal wieder ein neues Problem:
DB: Firebird Embedded 1.5
Ich habe einen Trigger mit Generator, der mir bei einem Insert automatisch eine Rechnungsnummer (RENR) in der Tabelle Rechungen erstellt (also immer um eins erhöht).
Damit ich aber in meine Tabelle Repostionen schreiben kann, brauche ich als Rückgabewert die RENR.
Ich habe mir das in etwa so gedacht:
Var KDNR, REDAT
SQL-Anweisung 1: 2: 3: 4: 5:
| BEGIN INSERT INTO RECHNUNGEN (KDNR,REDAT) VALUES (:KD_NR,:RE_DAT); SELECT RENR FROM Rechnungen WHERE RENR = Rechnungen.NEW.RENR INTO :RENR_OUT; SUSPEND; END |
Leider haut das mit dem Rechnungen.NEW.RENR nicht hin.
Ich könnte auch sagen:
SQL-Anweisung 1: 2: 3: 4:
| SELECT RENR FROM Rechnungen WHERE KDNR = :KD_NR AND REDAT = :RE_DAT INTO :RENR_OUT; SUSPEND; END |
So könnte ich allerdings nur eine Rechnung pro Tag an einen Kunden schreiben --> unkomfortabel
Falls ihr dazu eine Lösung habt wüsste ich dann auch noch gerne wie ich an den Rückgabewert von sql aus ran komme, denn momentan teste ich noch mit IBExert.
Danke im Vorraus
Gruß
Johannes
Moderiert von Christian S.: Delphi- durch SQL-Tags ersetzt
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Mi 28.06.06 19:06
Kommt mir irgendwie bekannt vor.  Aber, so wird nicht viel dabei rauskommen, denn :
1. ein Trigger kann keine Rückgabewertewerte liefern. Du versuchst die aber irgendwie zu bekommen.
2. es kommmt mir so vor, als wenn Du nicht bloß eine Rechnung pro Tag schreiben kannst, sondern sogar nur eine mit einer einzelnen Position drauf ! Auf Anhieb sehe ich jedenfalls nicht, wo die einmaligen Daten pro Rechnung herstammen sollen. Also Rechn.Nr. Kund.Nr., Datum usw.
Verwende für die Rechn.Nr. am besten eigene Tabelle ohne irgendwelchen Schnickschnack. Nicht mal eine ID und zähle die per SP hoch, liefere den Wert an das Programm und Basta. Ein Trigger ist hier völlig fehl am Platze.
_________________ Gruß
Hansa
|
|
jo-freaky 
      
Beiträge: 24
|
Verfasst: Mi 28.06.06 20:26
Ok, ich glaube wir reden aneinander vorbei.
1. ja das ist dein quellcoe den ich aus einem anderen Beitrag verwendet habe und ummodeln wollte um erstmal zu versuchen es selbst hinzubekommen, bevor ich euch wieder belästige - Fehlanzeige.
Kurz meine Tabellenstruktur:
Tab Rechnungen: RENR, KDNR, REDAT, RESUMME
Tab RePositionen: REPOS, RENR, ARTPREIS.... etc
Beim erstellen einer Rechnung wird zuerst in Tab Rechnungen KDNR und REDAT eingefügt, per Trigger wird RENR vergeben und genau die will ich zurückgeliefert bekommen.
Da dachte ich an eine SP mit der ich einen Insert von KDNR und REDAT mache und mir dann so die RENR (welche von o.g. separatem trigger erstellt wurde) zurückgeben zu lassen.
Ich weiss nicht ob ich da einen Denkfehler habe und am besten den Trigger in die SP einbauen soll/kann/muss!?
Für die Rechnungsendsumme habe ich wiederum einen eigenen Trigger der mir immer die Endsumme aller artikel berechnet und dies in Tabelle Rechnungen in RESUMME schreibt. (funktioniert bereits)
Zu 1. Der Quellcode ist ein Ausschnitt aus einer SP und wenn du den zweiten betrachtest funktioniert der auch, aber eben nur mit einer REchnung PRO TAG bei gleicher KDNR. //So bekomme ich einen Rückgabewert
Zu 2. siehe oben
Danke für die Mühe!
Gruß
Johannes
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Mi 28.06.06 22:30
Ersetze den Trigger durch eine SP, die sich per Generator die ID holt und diese zurückgibt.
_________________ Markus Kinzler.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 29.06.06 02:56
Oh, heiliger Johannes !
jo-freaky hat folgendes geschrieben: | Ok, ich glaube wir reden aneinander vorbei.
Beim erstellen einer Rechnung wird zuerst in Tab Rechnungen KDNR und REDAT eingefügt, per Trigger wird RENR vergeben und genau die will ich zurückgeliefert bekommen.
...
Ich weiss nicht ob ich da einen Denkfehler habe und am besten den Trigger in die SP einbauen soll/kann/muss!?
Für die Rechnungsendsumme habe ich wiederum einen eigenen Trigger der mir immer die Endsumme aller artikel berechnet und dies in Tabelle Rechnungen in RESUMME schreibt. (funktioniert bereits)
|
Nix aneinander vorbeireden. Ich weiß genau was du willst. Trigger, Trigger immer wieder Trigger. Was soll das ? Du mußt Dir schon die Mühe machen, zu verstehen, was der überhaupt macht. Und vor allem wann ! Und dann einen Trigger in eine SP einbauen ?  Guck lieber mal, was eine SP überhaupt kann. Der Trigger kann als scharfer Wachhund zubeißen, sofern in der SP ein Insert / Update oder Delete gemacht wird. Der ist jedenfalls einfach nur dumm und schlägt zu. Er kennt keine Parameter und keine Rückgabewerte. So und nicht anders ist die Lage.
Dann noch zu dem entsetzlichen hier :
[qoute]1. ja das ist dein quellcoe den ich aus einem anderen Beitrag verwendet habe und..[/quote]
Entweder war der uralt, oder du hast das nicht verstanden und komplett entstellt. Denn das was geht, das sieht so aus :
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| CREATE PROCEDURE RECNRSP RETURNS ( RECNR INTEGER) AS DECLARE VARIABLE NEUERECNR INTEGER; BEGIN NEUERECNR = -1; SELECT NR FROM RECNR INTO :NEUERECNR; IF (NEUERECNR < 0) THEN BEGIN INSERT INTO RECNR (NR) VALUES (1); RECNR = 1; END ELSE BEGIN UPDATE RECNR SET NR = NR + 1; RECNR = NEUERECNR + 1; END SUSPEND; END^ |
Das dient aber nur zum Ermitteln der laufenden Nr. !! DANACH muß ein leerer Datensatz erzeugt werden, der die Nummer erhält. --> Parameter. Der leere DS, bzw. nur Nr., Datum usw. wird dann in die Table eingefügt --> Trigger vergibt dadurch die ID_RECKOPF. Allerdings innnerhalb einer SP und diese gibt die ID (Output-Param) ans Programm weiter. Für die Positionen wird die ID der Rechnung (diesmal als Input-Param) verwendet und alles gespeichert. Wie kann man überhaupt versuchen, so etwas mit Triggern zu machen ?  Es ist echt entsetzlich.
Moderiert von Christian S.: Delphi- durch SQL-Tags ersetzt
_________________ Gruß
Hansa
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 29.06.06 06:41
@hansa: Dein Code ist aber nicht optimal, warum verwendest du keinen Generator?
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9:
| CREATE PROCEDURE RECNRSP RETURNS ( RECNR INTEGER) AS BEGIN RECNR = GEN_ID( GEN_RECH, 1); INSERT INTO RECNR (NR) VALUES (:RECNR); SUSPEND; END; |
_________________ Markus Kinzler.
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Do 29.06.06 10:35
Vergleiche dazu am besten die Diskussion hier. Dem Beitrag von mkinzler stimme ich voll zu. Wenn Du den Trigger von IBExpert hast generieren lassen, dann generiert diese nur eine ID, wenn diese nciht per Insert übergeben wird. Damit kannst Du in der SP den Generator abfragen und diesen Wert über das Insert übergeben, aber hast ihn trotzdem noch in der SP zur Rückgabe zur Verfügung.
Das ist die beste, komfortabelste und sicherste Lösung
//EDIT: @hansa: Wieso versuchst Du einen Generator nachzubauen? Wozu hat man denn diese, wenn Du das Rad schon wieder neu erfinden willst?
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 29.06.06 12:07
UGrohne hat folgendes geschrieben: | ...Das ist die beste, komfortabelste und sicherste Lösung
//EDIT: @hansa: Wieso versuchst Du einen Generator nachzubauen? Wozu hat man denn diese, wenn Du das Rad schon wieder neu erfinden willst? |
Das hat seine Gründe. Allerdings sehr wichtige, warum das von wegen sicher ist und keinesfalls so gemacht werden sollte. Was, wenn der User eine Startnummer haben will oder die Nr. soll zurückgesetzt werden ? Geht das mit Generator auch so einfach wie mit einer Table mit nur einem Wert ?  Egal. Jetzt aber noch der absolute K.O.  Generatoren unterliegen nicht der Transaktionssteuerung  Nix mehr mit Rollback usw. Also : schreibe Rechnung, Nr. wird vergeben. Nach 3 Positionen merke ich : falscher Kunde. Neuer Versuch : falsches Datum erwischt. Wieder wird alles rückgängig gemacht. 3. Anlauf : endlich geschafft. Mit der Datenbank wird noch alles stimmen. Bestände usw. Aber eines stimmt nun nicht mehr : die fortlaufende Rechnungsnnr. Man kann dann lediglich sicher sein, daß die neue Nr. zumindest größer als die davor ist.
_________________ Gruß
Hansa
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Do 29.06.06 13:49
hansa hat folgendes geschrieben: | Das hat seine Gründe. Allerdings sehr wichtige, warum das von wegen sicher ist und keinesfalls so gemacht werden sollte. Was, wenn der User eine Startnummer haben will oder die Nr. soll zurückgesetzt werden ? Geht das mit Generator auch so einfach wie mit einer Table mit nur einem Wert ? |
Ja, das geht, per SET GENERATOR ... TO;
hansa hat folgendes geschrieben: | Egal. Jetzt aber noch der absolute K.O. Generatoren unterliegen nicht der Transaktionssteuerung Nix mehr mit Rollback usw. Also : schreibe Rechnung, Nr. wird vergeben. Nach 3 Positionen merke ich : falscher Kunde. Neuer Versuch : falsches Datum erwischt. Wieder wird alles rückgängig gemacht. 3. Anlauf : endlich geschafft. Mit der Datenbank wird noch alles stimmen. Bestände usw. Aber eines stimmt nun nicht mehr : die fortlaufende Rechnungsnnr. Man kann dann lediglich sicher sein, daß die neue Nr. zumindest größer als die davor ist. |
Genau, man kann davon ausgehen, dass die Nummer größer ist. Aber davon abgesehen, was spielt es für eine Rolle, wenn eine Rechnungsnummer übergangen wird?
Wenn man die Eingaben macht, ist das ganze noch nicht in der Datenbank, spielt also keine Rolle. Wenn die Eingaben aber gemacht wurden und das ganze in der Datenbank steckt, dann kannst Du auch nicht einfach den Datensatz löschen lassen oder die Transaktion rückgängig machen, da muss dann ein Storno her, Du darfst buchhalterische Daten NICHT wieder löschen!
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 29.06.06 18:17
Stimmt SET GENERATOR. Aber das andere wird doch wohl nicht Dein Ernst sein ?  Seit 1.1.2004 (eventuell 2005) ist es gesetzlich vorgeschrieben, fortlaufende Rechnungsnummern zu haben !! Jeder mit Lücken darin, der gerät in Erklärungsnot. Erkläre mal einem Steuerprüfer, daß das lediglich an einem DB-Generator liegt.  Was darf nicht gelöscht werden ? Falsche Eingaben, die noch nicht commited sind ? Keiner ist gezwungen, seine Fehler auch noch endgültig abzuspeichern. Genau für solche Fälle sind doch Transaktionen da. Und da soll jetzt wegen zweifelhafter "Optimierungen", dazu noch eines einzigen Integers die Transaktionskontrolle ausgehebelt werden ? Gerade an einer sensiblen Stelle ? Lasse das mit dem Generator einfach weg und dann ist im Falle eines Rollback auch die aus Versehen zuviel vergebene Nr. wieder richtig.
_________________ Gruß
Hansa
|
|
jo-freaky 
      
Beiträge: 24
|
Verfasst: Do 29.06.06 18:41
Hey super vielen Dank mkinzler!!!
Das ist genau was ich brauche - funktioniert perfekt!!
Edngültig sieht mein Code jetzt so aus:
Delphi-Quelltext 1: 2: 3: 4: 5:
| BEGIN RE_NR = GEN_ID(GEN_RECHNUNGEN_ID, 1); INSERT INTO Rechnungen (RENR,KDNR,REDAT) VALUES (:RE_NR,:KDNR,:REDAT); SUSPEND; END |
@hansa: Ich fand deine Antwort irgendwie schroff und unpassend.
Ich stelle hier doch Fragen, weil ich es nicht besser weiss und gerne dazulernen möchte und nicht um jemanden zu nerven, weil ich nichts besseres zu tun habe! BTW...
Delphi-Quelltext 1: 2: 3:
| NEUERENR = -1; SELECT RENR FROM RECHNUNGEN INTO :NEUERENR; IF (NEUERENR < 0) THEN BEGIN |
Ich habe deinen Code ausprobiert und habe festgestellt, dass er leider nicht funtzt.
Kann es sein dass es an dem Select RENR...INTO liegt? Wenn nämlich schon mehrere DS vorhanden sind, würden doch mehrere Rechnungsnummern selektiert, oder nicht?
Falls ich deinen Gedankengang mal wieder nicht verstanden haben sollte, bitte ich um große Nachsicht!!
Ich trau mich schon fast nichtmehr zu fragen:
In IBExpert funktioniert der "SQL-Befehl" für die SP_Variante von mkinzler einwandfrei, wenn ich es allerdings aus Delphi versuche kommt eine Fehlermeldung à la : Exception - messaage length error(encountered 0, expected 16).. (Screenshot im Anhang)
Hier mein Delphi Code:
Delphi-Quelltext 1: 2: 3: 4:
| ReCreateQ.Close; ReCreateQ.SQL.Clear; ReCreateQ.SQL.Add('EXECUTE PROCEDURE REINSERTX('+QuotedStr('424')+',' + QuotedStr('01.01.2001')+');'); ReCreateQ.ExecSQL; |
Und noch eine Frage um euch den Rest zu geben:
Wie komme ich von Delphi aus an den Rückgabewert der SP?
Danke für eure Mühe und euer Durchhaltevermögen!
Gruß
Johannes
Einloggen, um Attachments anzusehen!
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 29.06.06 19:22
Zitat: | Wie komme ich von Delphi aus an den Rückgabewert der SP? |
Delphi-Quelltext 1: 2: 3: 4:
| ReCreateQ.Close; ReCreateQ.SQL.Clear; ReCreateQ.SQL.Add('select RE_NR from REINSERTX('+QuotedStr('424')+',' + QuotedStr( '01.01.2001')+');'); ReCreateQ.ExecSQL; |
_________________ Markus Kinzler.
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 29.06.06 20:55
Den Wert in Delphi auslesen ? Bei mir so :
Delphi-Quelltext 1: 2: 3:
| RecNrSP.ExecProc; BelegNr := RecNrSP.ParamByName ('RECNR').AsInteger; |
Was hat nicht funktioniert ? Bzw. wie hast Du sie getestet ? Hoffentlich zuerst in Ibexpert. Meine Bedenken haben mit Dir doch gar nichts zu tun. Sondern nur mit der Umgehung der Transaktionkontrolle. Das hier geht 100%ig :
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| SET TERM ^ ;
CREATE PROCEDURE RECNRSP RETURNS ( RECNR INTEGER) AS DECLARE VARIABLE NEUERECNR INTEGER; BEGIN NEUERECNR = -1; SELECT NR FROM RECNR INTO :NEUERECNR; IF (NEUERECNR < 0) THEN BEGIN INSERT INTO RECNR (NR) VALUES (1); RECNR = 1; END ELSE BEGIN UPDATE RECNR SET NR = NR + 1; RECNR = NEUERECNR + 1; END SUSPEND; END ^
SET TERM ; ^ |
In Script Executive kopieren (aber wirklich 1:1) und laufen lassen. Stop ! Vorher muß eine Table RECNR angelegt werden, aber ohne alles ! Keine ID, kein Trigger, kein Generator. Sie muß ein einzelnes Feld haben "NR integer". Und dann mal laufen lassen, Commit, Rollback und sich ansehen, was mit der Nr. passiert. Eventuell bereits vorhandene Table / SP vorher löschen. Mit dem Generator-Dingens kannstes ja auch mal testen.
nur @Uwe, Markus : Noch einmal Generator : schon mal überlegt, was im Netzwerk damit abläuft ? So in Richtung Netzwerkkabel ziehen, Serversicherung rausmachen ? Was wäre in dem einen und dem anderen Fall ?
_________________ Gruß
Hansa
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 29.06.06 21:37
@hansa: Generatoren können u.U. zu Lücken führen, deine Lösung zu doppelten Werten.
das von dir benannte Problem kann aber programmtechnisch umganen werden, indem man erst einfügt, wenn man sich sicher ist, das man es will. Sequencen/Generatoren sind bestandteil der meißten modernen DBMS und werden von vielen Programmen verwendet. IMHO verspühre ich für meinen Teil keinen Drang ihn selber nachzubauen. Die von dir erwähnte Vorschrift, wird aber auch erfüllt, wenn die Rechnungen als storniert markiert sind.
_________________ Markus Kinzler.
|
|
jo-freaky 
      
Beiträge: 24
|
Verfasst: Do 29.06.06 22:43
@hansa: Ja dein Code funktioniert, hab ne neue db angelegt mit den entsprechenden Tabellen, muss mir vorhin beim umschreiben vllt. ein Fehler unterlaufen sein.
Wenn ich jetzt allerdings die Variante von mkinzler verwende:
Delphi-Quelltext 1: 2: 3: 4:
| ReCreateQ.Close; ReCreateQ.SQL.Clear; ReCreateQ.SQL.Add('Select RE_NR from REINSERTX('+QuotedStr('424')+',' + QuotedStr('01.01.2001'+');'); ReCreateQ.ExecSQL; |
Dann funktioniert das soweit auch ganz prima, aber wie bekomme ich nun den Rückgabewert in eine Variable?
habe schon versucht:
Delphi-Quelltext 1:
| ReCreateQ.FieldbyName(RE_NR).AsInteger; |
Hier meckert der Compiler.
Danke und Gruß
Johannes
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 29.06.06 22:46
Delphi-Quelltext 1:
| id := ReCreateQ.FieldbyName('RE_NR').Value; |
_________________ Markus Kinzler.
|
|
jo-freaky 
      
Beiträge: 24
|
Verfasst: Do 29.06.06 22:54
Man geht das schnell hier
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| ReCreateQ.Close; ReCreateQ.SQL.Clear; ReCreateQ.SQL.Add('Select RE_NR from REINSERTX('+QuotedStr('424')+',' + QuotedStr('01.01.2001')+');'); ReCreateQ.Open; result:=ReCreateQ.FieldByName('re_nr').AsInteger; Edit2.Text:=IntToStr(result); |
das ist jetzt mein Code, der bei einem Klick auf einen Button ausgelöst wird.
Ich muss ReCreate.Open; verwenden, ansonsten habe ich keinen Rückgabewert. ??? <<<---- Richtig?
Egal ob ich nun .AsInteger oder .Value mache, ist mein zurückgelieferter wert komischerweise immer um 3 größer als der vorige und nicht genau um 1! Komisch oder?
//Edit1: Schau ich mit IBExpert in die Tabelle so sind aber alle Datensätze fortlaufend vorhanden, müssen wohl irgendwie anstelle von einem Insert drei passieren°!? *confused*
//Edit2: Sorry Sorry - vergessst das mit den 3mal... war eine Schleife!!!(wohl schon zu spät  )
Vielen Dank für eure großartige Hilfe!!!!!
Gruß
Johannes
Zuletzt bearbeitet von jo-freaky am Do 29.06.06 23:07, insgesamt 1-mal bearbeitet
|
|
mkinzler
      
Beiträge: 4106
Erhaltene Danke: 13
Delphi 2010 Pro; Delphi.Prism 2011 pro
|
Verfasst: Do 29.06.06 23:03
Zitat: | Ich muss ReCreate.Open; verwenden, ansonsten habe ich keinen Rückgabewert. |
Korrekt .ExecSQL liefert keinen Cursor. hab das in deinem Code vorher überlesen.
Zitat: | Egal ob ich nun .AsInteger oder .Value mache, ist mein zurückgelieferter wert komischerweise immer um 3 größer als der vorige und nicht genau um 1! Komisch oder? |
Da müßte man sich mal den ganzen Code ansehen um das abschätzen zu können. Hast du den trigger deaktiviert? Das .AsInteger habe ich durch .Value ersetzt, weil das Ergebnis ja schon ein Integer ist und daher nicht mehr gewandelt werden muß.
_________________ Markus Kinzler.
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: Fr 30.06.06 10:13
hansa hat folgendes geschrieben: | Stimmt SET GENERATOR. Aber das andere wird doch wohl nicht Dein Ernst sein ? Seit 1.1.2004 (eventuell 2005) ist es gesetzlich vorgeschrieben, fortlaufende Rechnungsnummern zu haben !! Jeder mit Lücken darin, der gerät in Erklärungsnot. |
Yapp, und genau deswegen darf so etwas auch nicht gelöscht werden. Die Stornierung muss ersichtlich sein und dann hast Du auch keine Erklärungsproblem mehr.
hansa hat folgendes geschrieben: | Erkläre mal einem Steuerprüfer, daß das lediglich an einem DB-Generator liegt. Was darf nicht gelöscht werden ? Falsche Eingaben, die noch nicht commited sind ? |
Und solange sie nicht commited sind, wird auch der Generator nicht angefasst, da dies erst beim Eintragen geschieht. Somit würde mir Deine Lösung nur noch mehr Probleme bringen. Eine commitede Transaktionen kannst Du auch nicht rückgängig machen. Und was machst Du wenn innerhalb einer Transaktion ein anderer User auch eine Rechnung schreiben will? Das darf er dann nicht? Oder mit dirty read? Dann hast Du dasselbe Problem wie mit dem Generator, wenn die andere Transaktion rückgängi gemacht wird. Und dann hast Du eine Lücke, die Du NICHT erklären kannst, weil es einfach keine Daten dazu gibt.
Genau das ist der Grund dafür, dass man in einer Buchhaltung normalerweise KEINERLEI Daten löschen kann, wenn sie einmal gespeichert wurden. Dann könnte ja jeder hergehen und die Datenbasis inkosistent machen (im betriebswirtschaftlichen Sinn).
hansa hat folgendes geschrieben: | Keiner ist gezwungen, seine Fehler auch noch endgültig abzuspeichern. Genau für solche Fälle sind doch Transaktionen da. Und da soll jetzt wegen zweifelhafter "Optimierungen", dazu noch eines einzigen Integers die Transaktionskontrolle ausgehebelt werden ? Gerade an einer sensiblen Stelle ? Lasse das mit dem Generator einfach weg und dann ist im Falle eines Rollback auch die aus Versehen zuviel vergebene Nr. wieder richtig. |
Eben und zu diesem Zeitpunkt hat der Generator auch noch keine ID vergeben. Jedenfalls in meinen Programmen.
//EDIT: Hab das Stichwort vergessen: Revisionssicherheit. Google mal danach, dann weißt Du was ich meine 
|
|
|