Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi fortlaufende Nr. (https://www.delphipraxis.net/13625-fortlaufende-nr.html)

Hansa 22. Dez 2003 20:28


fortlaufende Nr.
 
Hi,

ich bin dabei eine Rechnungstabelle zu coden. Diese besteht aus Kopfdatei mit den wichtigsten Daten (Rechn.Nr., Datum usw.) und einer Detailtabelle mit Artikeln etc. Die Rechn.Nr. soll fortlaufend nummeriert werden. Deshalb habe ich einen Before Insert Trigger:
SQL-Code:
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID (GEN_RECKOPF_ID,1);
    NEW.RECHNNR = GEN_ID (GEN_RECNR,1);
end
Ein Generator sorgt für die Erhöhung um 1. Bei einer neuen Rechnung wird also die ID und die Rechnungsnummer um 1 erhöht. In der Rechnungskopf-Datei steht das auch richtig drin, aber nicht in der Detail-Tabelle. Diese merkt nichts von der Erhöhung. Jetzt habe ich gelesen, daß man dazu eine Stored Procedure verwenden kann. Aber erstens finde ich das nicht mehr und zweitens komme ich von selber nicht dahinter. 8)

P.S.: Für die Rechn.Nr. habe ich eine separate Tabelle angelegt, die immer nur einen Eintrag aufnehmen soll. RDB$DATABASE will ich vorerst außer Acht lassen.

mschaefer 22. Dez 2003 20:50

Re: fortlaufende Nr.
 
Hallo Hansa,
jetzt ereilt dich vor Weihnachten auch noch das Rechnungsnummernproblem....

Du ich denke die Detailtabelle muß davon auch überhaupt nichts merken.
Sie darf nur nicht über die Rechnungsnummer an die Übersichts/Kopfdatentabelle
gebunden sein. Die Anbindung erfolt über den Priumärschlüssel der Kopftabelle.
Der ist als Sekundärschlüssel in der Detailtabelle.

Ablauf bei Dateineuanlage

1.) Es wird ein leerer Kopeintrag angelegt, ein Generator erhöht nur den Primärindex
2.) Ein zweiter generator erhöht die Rechnungsnummer
3.) Es wird ein leerer Detaildatensatz angelegt mit Generator wird ein Primärindex angelegt
4.) Im neuen Detaildatensatz wird als Sekundid die Primärid des Kopfeintrages eingetragen.

Jetzt sind die Artikeldatensätze nicht mit eigener Rechnungsnummer belegt, sondern an ihren Kopfeintrag gebunden der eine Rechnungsnummer hat.

Hoffe habe Deinen Weg so getroffen. Man kann das ja fast beliebig komplizieren.

Grüße aus dem verschneiten Hannover
// Martin

Hansa 26. Dez 2003 10:13

Re: fortlaufende Nr.
 
Zitat:

Zitat von mschaefer
jetzt ereilt dich vor Weihnachten auch noch das Rechnungsnummernproblem....

und das ich gerne über Weihnachten aus dem Weg räumen will, wenn der Schnee schon von alleine weg geht. :lol: Am einfachsten geht das so:
SQL-Code:
CREATE TABLE RECNR (NR INTEGER NOT NULL);

ALTER TABLE RECNR ADD CONSTRAINT PK_RECNR8 PRIMARY KEY (NR);

SET TERM ^ ;

CREATE TRIGGER RECNR_BI0 FOR RECNR
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  RECNR.nr = 1;
end

^
CREATE TRIGGER RECNR_BU0 FOR RECNR
ACTIVE BEFORE UPDATE POSITION 0
AS
begin
  new.nr = old.nr + 1;
end
^
Tja, mehr ist es nicht. Das einzige, worauf man achten muß, zumindest in meinem Beispiel muß die NR immer auf 0 gesetzt werden. Die Trigger setzen sie dann auf den richtigen Wert. Nur mit:
Delphi-Quellcode:
Edit;
Post;
geht es nicht. Im Delphi-Programm muß dazwischen noch folgendes stehen:

Delphi-Quellcode:
RecNrDS.FieldByName ('NR').AsInteger := 0

mschaefer 26. Dez 2003 11:38

Re: fortlaufende Nr.
 
Moin Hansa,

so ein bischen Weihnachtspause solltest Du Dir aucch gönnen. Kenne das mit den Weihnachtsproblemen. Man nimmt sich irgendwie immer was mit...

Also Deine Lösung sieht nach einem gangbaren Weg aus. Mit der seperaten Tabelle
ist das übrigens sehr geschickt. Damit kannst Du nämlich einen Auftrag anlegen
der zunächst keine Rechnugsnummer hat (weil vielleicht später auch gar keine
Rechnung geschreiben werden muß( Auftrag gecancelt,...)), sondern kannst die vor dem Rechnungsausdruck vergeben. Das mit der seperaten Tabelle ist auch mein Weg.

Habe in der Tabbelle auch noch Informationen über das letzte Drucckdatum und von
welchem Rechner aus (IP-Nummer). Ich ändere halt das letzte Rechnungsdatum und dabei wird der before Update Trigger ausgelöst. Damit mache ich das gleich wie Du.: Absenden eines Befehls zwischen Edit und Post, damit die Datenbank üerhaupt irgendetwas mitbekommt.


Viele Grüße aus Frisoythe
(es geht immer noch weiter nach Norden)


:xmas: :xmas: :xmas:


.

Hansa 1. Jan 2004 16:31

Re: fortlaufende Nr.
 
So, das Problem läßt sich am besten folgendermaßen lösen. Eine Stored Procedure ist in diesem Fall besser geeignet (ein Trigger ist zu eifrig) :

SQL-Code:
CREATE PROCEDURE RECNRSP
RETURNS (
    RECNR INTEGER)
AS
BEGIN
  EXIT;
END^

SET TERM ^ ;

ALTER 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
In Delphi habe ich nun noch diese Funktion, die die Rechn.Nr. zurückgibt:

Delphi-Quellcode:
function SucheNr : integer;
begin
  EingMod.RecNrSP.ExecProc;
  SucheNr := EingMod.RecNrSP.FieldByName ['RECNR'].AsInteger;
end;
Die Table RECNR enthält wirklich nur ein einziges integer Feld NR ! Kein Primary Key, sonst nichts. Mit obiger Konstruktion wird sie auch immer nur ein Feld beinhalten. Der Trick ist nicht schlecht. So kann man nämlich eine Unterscheidung, ob INSERT / UPDATE notwendig ist auf die Datenbank verlagern. Das Verfahren mit der lokalen Variablen läßt sich so auf alle Tabellen übertragen :!:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr.

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