Wie eindeutigen wert gewährleisten

hallo,

ich bin in pl/sql mehr als ein anfänger- deswegen hoffe ich das mir jemand helfen kann…

problemstellung:

für 3 firmen soll eine jeweils eindeutige fortlaufende rechnungsnummer garantiert werden.

meine überlegung
bei „update“ eines datensatzes mit der firmennummer soll eine prozedur laufen, die abfrägt welches die höchste rechnungsnummer für die firma und das jeweilige rechnungsjahr ermittelt, diese um 1 addiert und sie dem upgedateten datensatz hinzufügt

wie macht man das am besten? trigger??

vielen dank für eure hilfe

grüße

rasta

hi!

hm, verschiedene möglichkeiten (stand vor 3 jahren vor dem gleichen problem):

a) eigene nummerntabelle (sieht in etwas aus: firma, naechste_nummer)
b) vorm insert der rechnung ein „select nvl(max(re_nr),0)+1 into :re_nr from rechnungen where firma = :firma;“
c) mit einer prozedur
d) dieser punkt steht hier für noch weitere 3.712.129 möglichkeiten

ABER: unter oracle fall b) NICHT als db-trigger realisieren - und wenn doch, bekommst du einen schönen mutating-error

dazu kommt auch noch, daß du aufpassen mußt, falls eine rechnung gelöscht wird (diese nummer muß dann wieder verfügbar sein - falls löschen überhaupt möglich ist)

grüße,
tomh

ps: ich hab’s mit a) implementiert, da noch einige attribute die rechnungsnummer beeinflußten - nicht schön, aber es funktioniert

Hallo,
Ich würde es mit einer Sequenz versuchen (oder mit mehreren, einer pro Firma). Falls „Lücken“ verboten sind, scheidet dieser Ansatz allerdings aus.

a) eigene nummerntabelle (sieht in etwas aus: firma,
naechste_nummer)

Da sollte man aber mindestens einen unique-index auf (firma, re_nr) haben, sonst gibts irgendwann doch doppelte Rechnungsnummern. Und die evtl. auftretenden Fehler abfangen.

dazu kommt auch noch, daß du aufpassen mußt, falls eine
rechnung gelöscht wird (diese nummer muß dann wieder verfügbar
sein - falls löschen überhaupt möglich ist)

Gelöschte Rechnungsnummer neu vergeben? Erscheint mir gewagt :wink:.

Gruß, Uwe

hi!

Ich würde es mit einer Sequenz versuchen (oder mit mehreren,
einer pro Firma). Falls „Lücken“ verboten sind, scheidet
dieser Ansatz allerdings aus.

und das ist genau das, was zu befürchten ist

a) eigene nummerntabelle (sieht in etwas aus: firma,
naechste_nummer)

Da sollte man aber mindestens einen unique-index auf (firma,
re_nr) haben, sonst gibts irgendwann doch doppelte
Rechnungsnummern. Und die evtl. auftretenden Fehler abfangen.

mindestens; es sollten ev. noch mehrere felder wie jahr etc. (was ich aus der aufgabenstellung raushörte) dazugehören (zu tabelle + unique (primary?) key

Gelöschte Rechnungsnummer neu vergeben? Erscheint mir gewagt

ist gar nicht so abwegig!

rechnung wird „irrtümlich“ (falscher „knopf“ gedrückt bzw. „ich hab _gar_ nichts gemacht, die rechnung war plötzlich da!“) angelegt und schon hast den schlamassel …

grüße,
tomh

hi tom,

lücken in der rechnungsnummer sind erstmal erlaubt.

kannst du mir sagen, warum oracle bei einem trigger auf einen fehler laufen soll?

für jede firma eindeutige rechnungsnummer pro jahr(d.h. die nummer 1 kann in den jahren 2003 und 2004 vorhanden sein)

meine lösung ist so:

ich setze aus meinem vba-programm einen sql ab, der mir für die jeweilige firma und rechnungsnummer die höchste rechnungsnummer plus 1 schreibt.(demnach fällt eine sequenz aus, da ich keine werte übergeben kann)

anschliessend werden für diesen datensatz noch author, datum und sonstiges gezeter angefügt.

es könnte wahrscheinlich sein, das, wenn zur selben zeit diesselbe firma für das gleiche jahr ausgewählt wird, das die rechnungsnummer doppelt geschrieben wird.

für diesen fall wollte ich einen trigger basteln, der
mir aus ausgewähltem rechnungsjahr und rechnungsnummer in einem extra feld die unique-rechnungsnummer schreibt.

somit wäre eine eindeutige nummer auf jeden fall gewährleistet.

was meinst du/ihr

vielen dank für eure antworten

viele grüße

rasta

hi!

kannst du mir sagen, warum oracle bei einem trigger auf einen
fehler laufen soll?

für diesen fall wollte ich einen trigger basteln, der
mir aus ausgewähltem rechnungsjahr und rechnungsnummer in
einem extra feld die unique-rechnungsnummer schreibt.

somit wäre eine eindeutige nummer auf jeden fall
gewährleistet.

was meinst du/ihr

du willst ein select auf die selbe tabelle absetzen, in die die neue rechnung geinsertet (blödes wort, aber „eingefügt“ klingt so banal :wink: wird?
oracle error ora-???: table is mutating

zumindest bis 8.1.7 (und ich tippe auch ganz stark auch die höheren versionen): in einem datenbanktrigger (for insert/update/delete - after/before) darf man die betroffene Tabelle NICHT ansprechen - warum? weil du werte von einer tabelle holen willst, auf der gerade ein commit passiert und so die die tabelle „unpässlich“ ist, sprich: sie ist in einem undefinierten zustand (für die db ist das commit noch nicht durch, für die applikation schon, für die tabelle noch nicht ganz usw.)

grüße,
tomh

ps: threads, bei denen ich mitten drin bin, übersehe ich nicht so schnell - allerdings werde ich jetzt in den weihnachts"ferien" (ok, ich hab mir urlaub genommen :wink: wohl seltener hier reinschaun

hallo tom,

danke für deine antwort- das was du schreibst klingt sehr plausibel…
deswegen werde ich die mutation nicht austesten sondern mich gleich daran begeben ein unique-feld zu erstellen indas ich die mischung aus jahreszahl, firmennummer und rechnungsnummer schreibe…

somit ist eine doppelte vergabe ausgeschlossen

viele grüße

rasta

hi!

kannst du mir sagen, warum oracle bei einem trigger auf einen
fehler laufen soll?

für diesen fall wollte ich einen trigger basteln, der
mir aus ausgewähltem rechnungsjahr und rechnungsnummer in
einem extra feld die unique-rechnungsnummer schreibt.

somit wäre eine eindeutige nummer auf jeden fall
gewährleistet.

was meinst du/ihr

du willst ein select auf die selbe tabelle absetzen, in die
die neue rechnung geinsertet (blödes wort, aber „eingefügt“
klingt so banal :wink: wird?
oracle error ora-???: table is mutating

zumindest bis 8.1.7 (und ich tippe auch ganz stark auch die
höheren versionen): in einem datenbanktrigger (for
insert/update/delete - after/before) darf man die betroffene
Tabelle NICHT ansprechen - warum? weil du werte von einer
tabelle holen willst, auf der gerade ein commit passiert und
so die die tabelle „unpässlich“ ist, sprich: sie ist in einem
undefinierten zustand (für die db ist das commit noch nicht
durch, für die applikation schon, für die tabelle noch nicht
ganz usw.)

grüße,
tomh

ps: threads, bei denen ich mitten drin bin, übersehe ich nicht
so schnell - allerdings werde ich jetzt in den
weihnachts"ferien" (ok, ich hab mir urlaub genommen :wink: wohl
seltener hier reinschaun

hallo,

ich bin in pl/sql mehr als ein anfänger- deswegen hoffe ich
das mir jemand helfen kann…

problemstellung:

für 3 firmen soll eine jeweils eindeutige fortlaufende
rechnungsnummer garantiert werden.

Üblicherweise verwendet man in Oracle Sequences für diese Zwecke.
Ich habe die Syntax nicht im Kopf, erstellt wird diese aber in der Form

CREATE SEQUENCE tabelle1_id;

Im SQL verwendest du dann einfach die SEQUENCE, Oracle zählt sie automatisch hoch und das ganze ist Transaktionsicher:

INSERT INTO t_Tablle(n_ID,…) VALUES (tabelle1_id.nextval,…)

analog bei Update oder in PL/SQL Funktionen.

Wenn Oracle die ID automatisch bearbeiten soll, musst du die Sequenz wohl in einem Trigger verwalten, die Syntax habe ich aber nicht im Kopf. Wenn du die Statements selbst kontrollierst, halte ich Trigger jedoch für überflüssig.

Noch ein frohes Fest,

der Wortfuchs