Zum Inhalt springen

Oracle: laufende Nummer mit Sequenzen


Studdi20

Empfohlene Beiträge

Hallo zusammen,

ich versuche in einer Tabelle Datensätze einzufügen deren ID automatisch mit dem Befehl sequenzname.NEXTVAL erhöht wird. Beim Erstellen der Sequenz habe ich Start With 1 und als Inkrement auch 1 angegeben. Trotzdem wird beim Anlegen eines Datensatzes immer eine Nummer übersprüngen (2,4,6,8 usw.) Es ist aber für mich wichtig das die Nummer laufend ist ohne Lücken dazwischen, also 1,2,3,4 usw. Ein weiteres Problem besteht darin, dass wenn eine oder mehrere Einfügeoperationen fehlschlagen, beim nächsten erfolgreichen Einfügen sogar mehrere Nummern übersprüngen werden (z.b. 1,2,5,9 usw.)

Ich habe herausgefunden, dass wenn ich den Befehl .CURRVAL einsetze, also z.B. INSERT INTO TABLE VALUES (TAB_SEQ.CURRVAL, 'Test')

die Inkrementierung um 1 funktioniert jedoch nur wenn ich vorher NEXTVAL ausgeführt habe. Ansonsten erhalte ich folgende Fehlermeldung:

"ORA-08002: Sequenz TAB_SEQ.CURRVAL ist in dieser Session noch nicht definiert"

Ich möchte die SQL-Anweisung in einem Java-Programm verwenden und es ist wie schon gesagt wichtig, dass der erste Datensatz bei 1 anfängt und alle Anderen an die zuletzt eingetragene ID anknüpfen. Wie stelle ich das genau an? Gibt es vielleicht auch eine Möglichkeit nachträglich die Sequenz für eine Primärschlüsselspalte zu ändern bzw. neu zu erstellen, so dass alle ID's der Spalte den gewünschten Kriterien entsprechen?

Bearbeitet von Studdi20
Link zu diesem Kommentar
Auf anderen Seiten teilen

servus,

ja es handelt sich um ein BEFORE INSERT Trigger.

CREATE OR REPLACE TRIGGER  "BI_FAQS" 
before insert on "FAQS"
for each row
begin
select "FAQS_SEQ".nextval into :NEW.ID from dual;
end;

/
ALTER TRIGGER "BI_FAQS" ENABLE
/[/PHP]

Meinem Java-Programm übergebe ich folgende Zeichenkette um die eingegebenen Daten in der DB zu speichern:

String put = "INSERT INTO FAQS VALUES (faqs_seq.NEXTVAL, ?, ?, ?)";

PreparedStatement putStmt = connection.prepareStatement(put);

Aber wie gesagt, der Sequenz-Wert wird nicht wie erwartet beim Einfügen eines Datensatzes um 1 hochgezählt, sondern jeweils um 2. Die erste Zeile beginnt schon mit dem Wert 2. Woran liegt das und was genau muss ich ändern?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dir ist aber schon klar, was ein Trigger macht?

Zum Nachlesen: Triggers

Triggers are implicitly fired by Oracle when a triggering event occurs...

In deinem Fall ist das triggering event ein INSERT. Du benutzt einen BEFORE INSERT Trigger, also wird der Trigger natürlich vorher ausgeführt.

Du darfst in deinem INSERT die ID nicht nochmal mit dem Sequenzwert setzen, deshalb wird die Sequenz nämlich zweimal hochgesetzt. Einmal vom Trigger und einmal in deinem INSERT.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Achsooo :upps. Mir war nicht ganz klar wie ein Trigger arbeitet, sorry. Hab ihn jetzt deaktiviert und siehe da...es funzt :) Vielen Dank für deine Hilfe. Eine letzte Frage noch, ist es möglich eine Sequenz zurückzusetzen, so dass alle Datensätze einer Tabelle mit 1 beginnend eine laufende Nummerierung erhalten? Oder kann ich die Sequenz löschen und die Primärschlüsselspalte mit neuen Werten auffüllen?

EDIT: Hat sich erledigt, habs mit ALTER SEQUENCE hinbekommen.

Bearbeitet von Studdi20
Link zu diesem Kommentar
Auf anderen Seiten teilen

....Es ist aber für mich wichtig das die Nummer laufend ist ohne Lücken dazwischen, also 1,2,3,4 usw.....

EDIT: Hat sich erledigt, habs mit ALTER SEQUENCE hinbekommen.

Hallo,

Nur eine Bemerkung zu deiner Anforderung : "Lückenlose" Nummerierungen sind eine Illusion und können mit Sequences *nicht* garantiert werden.

Gruss

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

das ist mir mittlerweile klar geworden. Mein nächstes Ziel ist es einen Trigger zu schreiben der vor jedem insert max(id) sowie nextval ausliesst und die Sequenz anschließend um die Differenz inkrementiert. also z.b. sowas:

alter sequence faq_seq increment by maxid-value;

Nur kenn ich mich leider nicht mit PL/SQL aus und werde mich zuvor reinlesen müssen. So wie ich das in einem Tutorial verstanden habe muß ich erstmal in einem Package die Variablen definieren, in einem weiteren Trigger die Werte in den Variablen speichern und schließlich den Sequenzwert mit obigem Befehl anpassen.

Kann mir hierzu einer von euch Hilfestellung leisten? Wäre sehr dankbar.

Bearbeitet von Studdi20
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

das ist mir mittlerweile klar geworden. Mein nächstes Ziel ist es einen Trigger zu schreiben der vor jedem insert max(id) sowie nextval ausliesst und die Sequenz anschließend um die Differenz inkrementiert. also z.b. sowas:

- Das wird auch nicht funktionieren. Stichwort : Multiuser. Ich würde mir auf jeden Fall mal die Bedienung "Gap-Free" nochmals durch den Kopf gehen lassen, dies ist praktisch ohne Serialisierung nicht umzusetzten

Ein interesssanter Post zu diesem Thema findest du hier :

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:530735152441

Gruss

Bearbeitet von dbwizard
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...