Autor Beitrag
jo-freaky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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

ausblenden SQL-Anweisung
1:
2:
3:
4:
5:
BEGIN  
  INSERT INTO RECHNUNGEN (KDNR,REDAT) VALUES (:KD_NR,:RE_DAT);  /*Trigger vergibt hier schon die ID*/
  SELECT RENR FROM Rechnungen WHERE RENR = Rechnungen.NEW.RENR INTO :RENR_OUT; /* Ausgabe der aktuell erstellten Rechnungsnummer in RENR_OUT */
  SUSPEND;
END


Leider haut das mit dem Rechnungen.NEW.RENR nicht hin.
Ich könnte auch sagen:

ausblenden SQL-Anweisung
1:
2:
3:
4:
 
  SELECT RENR FROM Rechnungen WHERE KDNR = :KD_NR AND REDAT = :RE_DAT INTO :RENR_OUT; /* Ausgabe der aktuellen Rechnungsnummer in 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 user profile iconChristian S.: Delphi- durch SQL-Tags ersetzt
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mi 28.06.06 19:06 
Kommt mir irgendwie bekannt vor. 8) 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Do 29.06.06 02:56 
Oh, heiliger Johannes ! :lol:

user profile iconjo-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 ? :shock: 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 :

ausblenden 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 < 0THEN 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 ? :autsch: Es ist echt entsetzlich. :mrgreen:

Moderiert von user profile iconChristian S.: Delphi- durch SQL-Tags ersetzt

_________________
Gruß
Hansa
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Do 29.06.06 06:41 
@hansa: Dein Code ist aber nicht optimal, warum verwendest du keinen Generator?

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Do 29.06.06 12:07 
user profile iconUGrohne 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 ? :gruebel: Egal. Jetzt aber noch der absolute K.O. 8) 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Do 29.06.06 13:49 
user profile iconhansa 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;
user profile iconhansa hat folgendes geschrieben:
:gruebel: Egal. Jetzt aber noch der absolute K.O. 8) 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Do 29.06.06 18:17 
Stimmt SET GENERATOR. Aber das andere wird doch wohl nicht Dein Ernst sein ? :shock: 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. :lol: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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:
ausblenden 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...
ausblenden Delphi-Quelltext
1:
2:
3:
NEUERENR = -1;
  SELECT RENR FROM RECHNUNGEN INTO :NEUERENR;
  IF (NEUERENR < 0THEN 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:
ausblenden 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: 8)

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Do 29.06.06 19:22 
Zitat:
Wie komme ich von Delphi aus an den Rückgabewert der SP?

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Do 29.06.06 20:55 
Den Wert in Delphi auslesen ? Bei mir so :

ausblenden Delphi-Quelltext
1:
2:
3:
// SP-SQL : EXECUTE PROCEDURE RECNRSP
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 :

ausblenden 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 < 0THEN 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: 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:

ausblenden 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:
ausblenden Delphi-Quelltext
1:
ReCreateQ.FieldbyName(RE_NR).AsInteger;					


Hier meckert der Compiler.


Danke und Gruß
Johannes
mkinzler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: Do 29.06.06 22:46 
ausblenden Delphi-Quelltext
1:
id := ReCreateQ.FieldbyName('RE_NR').Value;					

_________________
Markus Kinzler.
jo-freaky Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 29.06.06 22:54 
Man geht das schnell hier ;-)

ausblenden 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 :autsch: )

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 4106
Erhaltene Danke: 13


Delphi 2010 Pro; Delphi.Prism 2011 pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 30.06.06 10:13 
user profile iconhansa hat folgendes geschrieben:
Stimmt SET GENERATOR. Aber das andere wird doch wohl nicht Dein Ernst sein ? :shock: 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.
user profile iconhansa hat folgendes geschrieben:
Erkläre mal einem Steuerprüfer, daß das lediglich an einem DB-Generator liegt. :lol: 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).

user profile iconhansa 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 ;)