Как получить текущее значение последовательности оракула без его увеличения?

Есть ли инструкция SQL для получения значения последовательности, которая не увеличивает ее.

Спасибо.

РЕДАКТИРОВАТЬ И ЗАКЛЮЧЕНИЕ

Как указано Джастин Кейв Не полезно пытаться "сохранить" порядковый номер, чтобы

select a_seq.nextval from dual;

достаточно хорош, чтобы проверить значение последовательности.

Я все еще держу Олли в качестве хорошего, потому что он ответил на начальный вопрос. но спросите себя о необходимости не изменять последовательность, если вы когда-либо захотите это сделать.

Ответ 1

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

Вы можете получить множество метаданных последовательности из user_sequences, all_sequences и dba_sequences.

Эти представления работают через сеансы.

EDIT:

Если последовательность находится в вашей схеме по умолчанию, то:

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

Если вы хотите все метаданные, то:

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

Надеюсь, что это поможет...

EDIT2:

Долговечный способ сделать это более надежно, если размер вашего кеша не равен 1:

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.

Просто будьте осторожны, если другие используют эту последовательность в течение этого времени - они (или вы) могут получить

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

Кроме того, вы можете установить кеш на NOCACHE до сброса, а затем вернуться к своему первоначальному значению, чтобы убедиться, что вы не кэшировали множество значений.

Ответ 2

select MY_SEQ_NAME.currval from DUAL;

Имейте в виду, что он работает только в том случае, если вы запускали select MY_SEQ_NAME.nextval from DUAL; в текущих сеансах.

Ответ 3

Мой первоначальный ответ был фактически неверным, и я рад, что он был удален. Приведенный ниже код будет работать при следующих условиях: а) вы знаете, что никто другой не изменил последовательность; б) последовательность была изменена вашей сессией. В моем случае я столкнулся с аналогичной проблемой, когда я вызывал процедуру, которая меняла значение, и я уверен, что предположение верно.

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

К сожалению, если вы не изменили последовательность в своей сессии, я считаю, что другие верны, заявив, что NEXTVAL - единственный способ пойти.

Ответ 4

На самом деле это не ответ, и я бы написал его как комментарий, если бы вопрос не был заблокирован. Это отвечает на вопрос:

Зачем тебе это?

Предположим, у вас есть таблица с последовательностью в качестве первичного ключа, и последовательность генерируется триггером вставки. Если вы хотите, чтобы последовательность была доступна для последующих обновлений записи, вам нужен способ извлечь это значение.

Чтобы убедиться, что вы получите правильный вариант, вы можете заключить запрос INSERT и RonK в транзакцию.

RonK Query:

select MY_SEQ_NAME.currval from DUAL;

В приведенном выше сценарии предупреждение RonK не применяется, поскольку вставка и обновление будут происходить в одном сеансе.

Ответ 5

Я также попытался использовать CURRVAL, в моем случае, чтобы выяснить, вставил ли какой-то процесс новые строки в какую-либо таблицу с такой последовательностью в качестве Первичного ключа. Я предполагал, что CURRVAL будет самым быстрым методом. Но a) CurrVal не работает, он просто получит старое значение, потому что вы находитесь в другом сеансе Oracle, пока вы не выполните NEXTVAL в своем собственном сеансе. И б) select max(PK) from TheTable также очень быстр, вероятно, потому что PK всегда индексируется. Или select count(*) from TheTable. Я все еще экспериментирую, но оба SELECT кажутся быстрыми.

Я не возражаю против пробела в последовательности, но в моем случае я много думал об опросе, и я бы не хотел представлять себе очень большие пробелы. Особенно, если простой SELECT будет таким же быстрым.

Вывод:

  • CURRVAL довольно бесполезен, поскольку он не обнаруживает NEXTVAL из другого сеанса, он возвращает только то, что вы уже знали из своего предыдущего NEXTVAL
  • SELECT MAX (...) FROM... является хорошим решением, простым и быстрым, при условии, что ваша последовательность связана с этой таблицей