web-dev-qa-db-ja.com

インクリメントせずにOracleシーケンスの現在値を取得する方法

増分しないシーケンスの値を取得するためのSQL命令がありますか。

ありがとう。

編集と結論

Justin Caveが述べたように、シーケンス番号を "保存"しようとするのは役に立ちません。

select a_seq.nextval from dual;

シーケンス値をチェックするのに十分です。

それは最初の質問に答えたので私はまだOllieの答えを良いものとして保っています。あなたが今までそれをしたいならば、しかし、シーケンスを変更しないことの必要性についてあなた自身に尋ねてください。

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

user_sequencesall_sequencesおよびdba_sequencesからさまざまなシーケンスメタデータを取得できます。

これらのビューはセッションをまたがって機能します。

編集:

シーケンスがデフォルトのスキーマ内にある場合は、次のようになります。

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に設定し、その後元の値に戻すことをお勧めします。

152
Ollie

select MY_SEQ_NAME.currval from DUAL;

現在のセッションでselect MY_SEQ_NAME.nextval from DUAL;を実行した場合にのみ機能することに注意してください。

114
RonK

私の最初の返事は実際には間違っていました、そしてそれが取り除かれてうれしいです。以下のコードは、以下の条件で動作します。a)他の人がシーケンスを変更したことがないことを確認している。b)シーケンスがセッションによって変更されたこと。私の場合は、値を変更するプロシージャを呼び出していて、その仮定が正しいと確信しているという同様の問題に遭遇しました。

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

悲しいことに、あなたがあなたのセッションでシーケンスを変更しなかったならば、私は他人がNEXTVALが行く唯一の方法であると述べることにおいて正しいと信じています。

0
georgejo

これは答えではありません。質問がロックされていない場合はコメントとして入力したはずです。これは質問に答えます:

なぜあなたはそれが欲しいですか?

シーケンスを主キーとして持つテーブルがあり、シーケンスが挿入トリガによって生成されるとします。その後のレコードの更新にシーケンスを使用できるようにしたい場合は、その値を抽出する方法が必要です。

確実に正しいものを取得するために、INSERTとRonKのクエリをトランザクションにラップすることをお勧めします。

RonKの質問:

select MY_SEQ_NAME.currval from DUAL;

上記のシナリオでは、挿入と更新は同じセッションで行われるため、RonKの警告は適用されません。

0
Ainsworth

私の場合、CURRVALを使用して、プロセスが主キーとしてそのシーケンスを使用してテーブルに新しい行を挿入したかどうかを調べました。私の仮定は、CURRVALが最速の方法になるだろうということでした。ただし、a)CurrValは機能しません。自分のセッションでNEXTVALを実行するまで、別のOracleセッションにいるため、古い値が取得されます。また、b)select max(PK) from TheTableも非常に高速です。これは、おそらくPKが常にインデックス付けされるためです。またはselect count(*) from TheTable。私はまだ実験中ですが、両方のSELECTが高速に見えます。

シーケンスのギャップは気にしませんが、私の場合はポーリングをたくさん考えていたので、非常に大きなギャップのアイデアは嫌いです。特に、単純なSELECTが同じくらい速い場合。

結論:

  • CURRVALは、別のセッションからNEXTVALを検出せず、以前のNEXTVALから既に知っていたもののみを返すため、ほとんど役に立ちません。
  • SELECT MAX(...)FROM ...は、シーケンスがそのテーブルにリンクされていると仮定すると、シンプルで高速な優れたソリューションです。
0
Roland