![]() |
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:
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)
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID (GEN_RECKOPF_ID,1); NEW.RECHNNR = GEN_ID (GEN_RECNR,1); end 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. |
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 |
Re: fortlaufende Nr.
Zitat:
SQL-Code:
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:
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 ^
Delphi-Quellcode:
geht es nicht. Im Delphi-Programm muß dazwischen noch folgendes stehen:
Edit;
Post;
Delphi-Quellcode:
RecNrDS.FieldByName ('NR').AsInteger := 0
|
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: . |
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:
In Delphi habe ich nun noch diese Funktion, die die Rechn.Nr. zurückgibt:
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
Delphi-Quellcode:
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 :!:
function SucheNr : integer;
begin EingMod.RecNrSP.ExecProc; SucheNr := EingMod.RecNrSP.FieldByName ['RECNR'].AsInteger; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 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 by Thomas Breitkreuz