it-swarm.com.de

Wie kann man den aktuellen Wert einer Oracle-Sequenz abrufen, ohne ihn zu erhöhen?

Gibt es eine SQL-Anweisung zum Abrufen des Werts einer Sequenz, die diese nicht erhöht?.

Vielen Dank.

BEARBEITEN UND SCHLUSSFOLGERUNG

Wie von Justin Cave angegeben, ist es nicht sinnvoll, die Sequenznummer so zu "speichern"

select a_seq.nextval from dual;

ist gut genug, um einen Sequenzwert zu überprüfen.

Ich behalte die Ollie-Antwort immer noch als die gute, weil sie die ursprüngliche Frage beantwortet hat. Aber fragen Sie sich, ob es notwendig ist, die Reihenfolge nicht zu ändern, wenn Sie dies jemals möchten.

139
frno
SELECT last_number
  FROM all_sequences
 WHERE sequence_owner = '<sequence owner>'
   AND sequence_name = '<sequence_name>';

Sie können eine Vielzahl von Sequenzmetadaten aus user_sequences, all_sequences und dba_sequences.

Diese Ansichten funktionieren sitzungsübergreifend.

EDIT:

Wenn sich die Sequenz in Ihrem Standardschema befindet, gilt Folgendes:

SELECT last_number
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

Wenn Sie alle Metadaten möchten, gehen Sie wie folgt vor:

SELECT *
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

Ich hoffe es hilft...

EDIT2:

Ein langwieriger Weg, dies zuverlässiger zu machen, wenn Ihre Cache-Größe nicht 1 ist, wäre:

SELECT increment_by I
  FROM user_sequences
 WHERE sequence_name = 'SEQ';

      I
-------
      1

SELECT seq.nextval S
  FROM dual;

      S
-------
   1234

-- Set the sequence to decrement by 
-- the same as its original increment
ALTER SEQUENCE seq 
INCREMENT BY -1;

Sequence altered.

SELECT seq.nextval S
  FROM dual;

      S
-------
   1233

-- Reset the sequence to its original increment
ALTER SEQUENCE seq 
INCREMENT BY 1;

Sequence altered.

Achten Sie nur darauf, dass andere (oder Sie) die Sequenz während dieser Zeit verwenden

ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated

Möglicherweise möchten Sie den Cache vor dem Zurücksetzen auf NOCACHE und anschließend auf den ursprünglichen Wert zurücksetzen, um sicherzustellen, dass nicht viele Werte zwischengespeichert wurden.

156
Ollie

select MY_SEQ_NAME.currval from DUAL;

Denken Sie daran, dass es nur funktioniert, wenn Sie select MY_SEQ_NAME.nextval from DUAL; in den aktuellen Sitzungen.

115
RonK

Meine ursprüngliche Antwort war sachlich falsch und ich bin froh, dass sie entfernt wurde. Der folgende Code funktioniert unter den folgenden Bedingungen: a) Sie wissen, dass niemand die Sequenz geändert hat. B) Die Sequenz wurde von Ihrer Sitzung geändert. In meinem Fall bin ich auf ein ähnliches Problem gestoßen, bei dem ich eine Prozedur aufgerufen habe, mit der ein Wert geändert wurde, und ich bin überzeugt, dass die Annahme wahr ist.

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

Leider, wenn Sie die Reihenfolge in Ihrer Sitzung nicht geändert haben, sind andere der Meinung, dass NEXTVAL der einzige Weg ist.

0
georgejo

Dies ist eigentlich keine Antwort, und ich hätte sie als Kommentar eingegeben, wenn die Frage nicht gesperrt worden wäre. Dies beantwortet die Frage:

Warum willst du es?

Angenommen, Sie haben eine Tabelle mit der Sequenz als Primärschlüssel und die Sequenz wird durch einen Einfügetrigger generiert. Wenn Sie die Sequenz für spätere Aktualisierungen des Datensatzes verfügbar haben möchten, müssen Sie über eine Möglichkeit verfügen, diesen Wert zu extrahieren.

Um sicherzustellen, dass Sie das Richtige finden, möchten Sie möglicherweise die INSERT- und RonK-Abfrage in eine Transaktion einschließen.

RonKs Frage:

select MY_SEQ_NAME.currval from DUAL;

In dem obigen Szenario gilt die Einschränkung von RonK nicht, da das Einfügen und Aktualisieren in derselben Sitzung erfolgen würde.

0
Ainsworth

Ich habe auch versucht, CURRVAL zu verwenden, um in meinem Fall herauszufinden, ob ein Prozess neue Zeilen in eine Tabelle mit dieser Sequenz als Primärschlüssel eingefügt hat. Ich ging davon aus, dass CURRVAL die schnellste Methode ist. Aber a) CurrVal funktioniert nicht, es wird nur der alte Wert erhalten, weil Sie sich in einer anderen Oracle-Sitzung befinden, bis Sie eine NEXTVAL in Ihrer eigenen Sitzung durchführen. Und b) a select max(PK) from TheTable ist auch sehr schnell, wahrscheinlich, weil eine PK immer indiziert ist. Oder select count(*) from TheTable. Ich experimentiere immer noch, aber beide SELECTs scheinen schnell zu sein.

Ich habe nichts gegen eine Lücke in einer Sequenz, aber in meinem Fall habe ich viel darüber nachgedacht, abzufragen, und ich würde die Idee von sehr großen Lücken hassen. Vor allem, wenn ein einfaches SELECT genauso schnell wäre.

Fazit:

  • CURRVAL ist ziemlich nutzlos, da es NEXTVAL nicht aus einer anderen Sitzung erkennt, sondern nur das zurückgibt, was Sie bereits von Ihrem vorherigen NEXTVAL gewusst haben
  • SELECT MAX (...) FROM ... ist eine gute, einfache und schnelle Lösung, vorausgesetzt, Ihre Sequenz ist mit dieser Tabelle verknüpft
0
Roland