Reputation: 2871
Is there an SQL instruction to retrieve the value of a sequence that does not increment it.
Thanks.
EDIT AND CONCLUSION
As stated by Justin Cave It's not useful to try to "save" sequence number so
select a_seq.nextval from dual;
is good enough to check a sequence value.
I still keep Ollie answer as the good one because it answered the initial question. but ask yourself about the necessity of not modifying the sequence if you ever want to do it.
Upvotes: 217
Views: 750663
Reputation: 129
We can use the below query to get the sequence next value.
select last_number from dba_sequences where sequence_name = '<sequence name>';
Upvotes: 3
Reputation: 17538
SELECT last_number
FROM all_sequences
WHERE sequence_owner = '<sequence owner>'
AND sequence_name = '<sequence_name>';
You can get a variety of sequence metadata from user_sequences
, all_sequences
and dba_sequences
.
These views work across sessions.
EDIT:
If the sequence is in your default schema then:
SELECT last_number
FROM user_sequences
WHERE sequence_name = '<sequence_name>';
If you want all the metadata then:
SELECT *
FROM user_sequences
WHERE sequence_name = '<sequence_name>';
EDIT2:
A long winded way of doing it more reliably if your cache size is not 1 would be:
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.
Just beware that if others are using the sequence during this time - they (or you) may get
ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated
Also, you might want to set the cache to NOCACHE
prior to the resetting and then back to its original value afterwards to make sure you've not cached a lot of values.
Upvotes: 219
Reputation: 3318
The follows is often used:
select field_SQ.nextval from dual; -- it will increase the value by 1 for each run
select field_SQ.currval from DUAL;
However the following is able to change the sequence to what you expected. The 1
can be an integer (negative or positive)
alter sequence field_SQ increment by 1 minvalue 0
Upvotes: 11
Reputation: 2080
If your use case is that some backend code inserts a record, then the same code wants to retrieve the last insert id, without counting on any underlying data access library preset function to do this, then, as mentioned by others, you should just craft your SQL query using SEQ_MY_NAME.NEXTVAL
for the column you want (usually the primary key), then just run statement SELECT SEQ_MY_NAME.CURRVAL FROM dual
from the backend.
Remember, CURRVAL is only callable if NEXTVAL has been priorly invoked, which is all naturally done in the strategy above...
Upvotes: 2
Reputation: 5226
I also tried to use CURRVAL, in my case to find out if some process inserted new rows to some table with that sequence as Primary Key. My assumption was that CURRVAL would be the fastest method. But a) CurrVal does not work, it will just get the old value because you are in another Oracle session, until you do a NEXTVAL in your own session. And b) a select max(PK) from TheTable
is also very fast, probably because a PK is always indexed. Or select count(*) from TheTable
. I am still experimenting, but both SELECTs seem fast.
I don't mind a gap in a sequence, but in my case I was thinking of polling a lot, and I would hate the idea of very large gaps. Especially if a simple SELECT would be just as fast.
Conclusion:
Upvotes: 1
Reputation: 79
This is not an answer, really and I would have entered it as a comment had the question not been locked. This answers the question:
Why would you want it?
Assume you have a table with the sequence as the primary key and the sequence is generated by an insert trigger. If you wanted to have the sequence available for subsequent updates to the record, you need to have a way to extract that value.
In order to make sure you get the right one, you might want to wrap the INSERT and RonK's query in a transaction.
RonK's Query:
select MY_SEQ_NAME.currval from DUAL;
In the above scenario, RonK's caveat does not apply since the insert and update would happen in the same session.
Upvotes: 3
Reputation: 25
My original reply was factually incorrect and I'm glad it was removed. The code below will work under the following conditions a) you know that nobody else modified the sequence b) the sequence was modified by your session. In my case, I encountered a similar issue where I was calling a procedure which modified a value and I'm confident the assumption is true.
SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;
Sadly, if you didn't modify the sequence in your session, I believe others are correct in stating that the NEXTVAL is the only way to go.
Upvotes: -2
Reputation: 9652
select MY_SEQ_NAME.currval from DUAL;
Keep in mind that it only works if you ran select MY_SEQ_NAME.nextval from DUAL;
in the current sessions.
Upvotes: 157