Gibt es eine SQL-Anweisung, um den Wert einer Sequenz abzurufen, die ihn nicht erhöht?
Vielen Dank.
EDIT 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 Ollie immer noch als die gute Antwort, weil sie die ursprüngliche Frage beantwortet hat. Fragen Sie sich jedoch nach der Notwendigkeit, die Sequenz nicht zu ändern, wenn Sie dies jemals tun möchten.
nextval
die Sequenz zum Testen bringt? Sie gehen nicht davon aus, dass Sequenzen lückenlos sind, oder? Das "Verschwenden" eines Sequenzwerts sollte also kein Problem sein.Antworten:
Sie können eine Vielzahl von Sequenz Metadaten aus erhalten
user_sequences
,all_sequences
unddba_sequences
.Diese Ansichten funktionieren sitzungsübergreifend.
BEARBEITEN:
Wenn sich die Sequenz in Ihrem Standardschema befindet, dann:
Wenn Sie alle Metadaten möchten, dann:
Ich hoffe es hilft...
EDIT2:
Ein langwieriger Weg, dies zuverlässiger zu tun, wenn Ihre Cache-Größe nicht 1 ist, wäre:
Beachten Sie nur, dass andere (Sie) die Sequenz möglicherweise während dieser Zeit verwenden
Möglicherweise möchten Sie den Cache auch
NOCACHE
vor dem Zurücksetzen auf und anschließend auf den ursprünglichen Wert zurücksetzen, um sicherzustellen, dass Sie nicht viele Werte zwischengespeichert haben.quelle
ALL_SEQUENCES
ist eine Ansicht. Wenn Sie keinen Zugriff darauf haben, wählen Sie aus,USER_SEQUENCES
ob sich die Sequenz in Ihrem Standardschema befindet. (Sie brauchen diesequence_owner = '<sequence_owner>'
Klausel nicht fürUSER_SEQUENCES
).LAST_NUMBER
InALL_SEQUENCES
ist nicht die letzte Nummer, die einer Sitzung tatsächlich gegeben wurde, und es ist nicht die Nummer, die von einem Anruf ansequence_name.nextval
im Allgemeinen zurückgegeben wird. Angenommen, Sie haben die Sequenz aufCACHE
mehr als 1 festgelegt (der Standardwert ist 20),LAST_NUMBER
ist dies die letzte Nummer im Cache. Es gibt keine Garantie dafür, dass diese Nummer jemals einer Sitzung zugewiesen wird.ALTER SEQUENCE seq INCREMENT BY -1;
wird ein Problem sein, es sei denn, man kann garantieren , dass keine andere Sitzung anruftseq.nextval
. Andernfalls werden in der Sequenz doppelte Werte ausgegeben, was normalerweise nicht der Fall ist.select MY_SEQ_NAME.currval from DUAL;
Beachten Sie, dass dies nur funktioniert, wenn Sie
select MY_SEQ_NAME.nextval from DUAL;
in den aktuellen Sitzungen ausgeführt haben.quelle
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 anderes die Sequenz geändert hat. B) Die Sequenz wurde von Ihrer Sitzung geändert. In meinem Fall ist ein ähnliches Problem aufgetreten, bei dem ich eine Prozedur aufgerufen habe, die einen Wert geändert hat, und ich bin zuversichtlich, dass die Annahme wahr ist.
Wenn Sie die Reihenfolge in Ihrer Sitzung nicht geändert haben, sind andere leider der Meinung, dass NEXTVAL der einzige Weg ist.
quelle
Dies ist wirklich 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 von einem Insert-Trigger generiert. Wenn Sie die Sequenz für nachfolgende Aktualisierungen des Datensatzes verfügbar haben möchten, müssen Sie eine Möglichkeit haben, diesen Wert zu extrahieren.
Um sicherzustellen, dass Sie die richtige erhalten, möchten Sie möglicherweise die INSERT- und RonK-Abfrage in eine Transaktion einschließen.
RonKs Frage:
Im obigen Szenario gilt die Einschränkung von RonK nicht, da das Einfügen und Aktualisieren in derselben Sitzung erfolgen würde.
quelle
Ich habe auch versucht, CURRVAL zu verwenden, um 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 sein würde. Aber a) CurrVal funktioniert nicht, es erhält nur den alten Wert, weil Sie sich in einer anderen Oracle-Sitzung befinden, bis Sie in Ihrer eigenen Sitzung ein NEXTVAL durchführen. Und b) a
select max(PK) from TheTable
ist auch sehr schnell, wahrscheinlich weil eine PK immer indiziert ist. Oderselect 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 darüber nachgedacht, viel abzufragen, und ich würde die Idee sehr großer Lücken hassen. Besonders wenn ein einfaches SELECT genauso schnell wäre.
Fazit:
quelle