シーケンス参照

シーケンスを参照するには、NEXT VALUE 式と PREVIOUS 式を使用して、シーケンスの名前を指定します。

sequence-reference

構文図を読むビジュアルシンタックスダイアグラムをスキップするNEXT VALUE FORsequence-namePREVIOUS VALUE FORsequence-name
NEXT VALUE FOR シーケンス名
NEXT VALUE 式は、指定したシーケンスの次の値を生成して戻します。 NEXT VALUE 式がシーケンスの名前を指定している場合は、シーケンスに対して新しい値が生成されます。 しかし、クエリ内で同じシーケンス名を指定するNEXT VALUE式が複数存在する場合、シーケンス値は結果の各行に対して1回だけインクリメントされ、すべてのインスタンスが NEXT VALUE 結果の行に対して同じ値を返します。 その NEXT VALUE 外部からのアクションによってシーケンス値がインクリメントされるため、この式は決定論的ではありません。

シーケンスの次の値が生成される際に、シーケンスの論理範囲における昇順シーケンスの最大値または降順シーケンスの最小値を超え、 NO CYCLE オプションが有効になっている場合、エラーが発生します。 このエラーを防止するには、シーケンス属性を変更して値の範囲を拡大するか、 シーケンスの循環を使用可能に設定するか、あるいはシーケンスをドロップし、より大きな値の範囲を指定できる別のデータ・タイプを使用してシーケンスを再作成します。

NEXT VALUE 式の結果のデータ・タイプと長さ属性は、指定したシーケンスのものと同じです。 結果が NULL 値になることはありません。

PREVIOUS VALUE FOR シーケンス名
PREVIOUS VALUE 式は、現行アプリケーション・プロセス内の直前の ステートメントに指定されたシーケンスについて最後に生成された値を返します。 PREVIOUS VALUE 式を使用してシーケンス名を指定すると、この値を繰り返し参照できます。 単一のステートメントに、同じシーケンス名を指定する PREVIOUS VALUE 式のインスタンスが複数あっても構わず、これらはすべて同じ値を戻します。

PREVIOUS VALUE 式は、同じシーケンス名を指定する NEXT VALUE 式が現行アプリケーション・プロセス内で既に参照された場合にのみ使用できます。

PREVIOUS VALUE 式の結果のデータ・タイプと長さ属性は、指定したシーケンスのものと同じです。 結果が NULL 値になることはありません。

シーケンス名
参照対象のシーケンスを指定します。 名前と暗黙または明示のスキーマ名の組み合わせにより、現行サーバーに既に存在するシーケンスを指定する必要があります。 sequence-nameはDb2 によって生成されるアイデンティティ・カラム用の内部シーケンス・オブジェクトの名前であってはなりません。

変更の開始非修飾シーケンス名の暗黙の修飾子がどのように決定されるかについては、 非修飾オブジェクト名の解決を参照のこと。変更の終わり

許可:
あるステートメントの中でシーケンスが参照される場合、そのステートメントの許可 ID が保有する特権には、以下のいずれかが少なくとも 1 つ含まれている必要があります。
  • このステートメントで指定されたシーケンスに対して:
    • シーケンスに対する USAGE 特権
    • シーケンスの所有権
  • 変更の開始SYSADM または DATAACCESS 権限変更の終わり
NEXT VALUE を指定して値を生成:
シーケンスについて値が生成されると、その値を再使用できなくなるため、 次に値が要求されたときに新しい値が生成されます。 NEXT VALUE 式が組み込まれているステートメントが失敗した場合やロールバックされた場合でも、 これが当てはまります。
NEXT VALUE および PREVIOUS VALUE の有効範囲:
直接 PREVIOUS VALUE の値を設定することはできず、シーケンスに関する NEXT VALUE 式の実行結果として得られます。 PREVIOUS VALUE の値は、現行セッションでシーケンスに対して次の値が生成されるか、シーケンスがドロップまたは変更されるか、アプリケーション・セッションが終了するまで存続します。

ローカルまたはリモートアプリケーションのCOMMITまたはROLLBACKの後に、何らかのスレッドの再利用、再サインオン、またはコネクション・プーリングが有効になっているために、 Db2 アプリケーションスレッドまたはサーバースレッドが他のユーザーに割り当てられたり、 Db2 接続に割り当てられたりした場合、シーケンスの値はCOMMITまたはROLLBACKをまたいで持続することはできません。 例えば、 CICS® -Db2 アプリケーションや、クライアントアプリケーションまたはミドルウェア製品で、セッションの状態を保存し、その後の処理のためにセッションの状態を復元する場合に、シーケンスの「次」または「前」の値を復元できないために、このような問題が発生することがあります。 この場合、シーケンスの値を使用できるのは、トランザクションが終わるまでです。 このような状況が発生する可能性がある場合の例として、以下を行うアプリケーションがあります。

  • EXEC CICS SYNCPOINT コマンドを発行する
  • XA プロトコルを使用する
  • 接続プーリングを使用する
  • 接続コンセントレーターを使用する
  • シスプレックス・ワークロード・バランシングを使用する
  • z/OS® サーバーに接続し、DDF非アクティブスレッドを使用する

スレッド再使用、再サインオン、または接続プーリングに従うローカル・アプリケーションまたは分散アプリケーションのトランザクション境界を超えて NEXT VALUE 式または PREVIOUS VALUE 式に関連付けられた値を保持する必要がある場合は、以下のいずれかのアクションを実行して、ローカル・スレッドまたはサーバー・スレッドで再サインオン、別のユーザーによる再使用、またはプーリングが発生しないようにします。

  • 少なくとも 1 つのカーソルを WITH HOLD として定義し、OPEN にしておく。
  • バインド・オプション KEEPDYNAMIC(YES) を指定する。
ユニーク・キー値として使用:
以下の例に示すように、同じシーケンス番号を、 2 つの異なる表のユニーク・キー値として使用することができます。 これは、最初の行では NEXT VALUE 式 (これはシーケンス値を生成します) で、 その他の行では PREVIOUS VALUE 式 (PREVIOUS VALUE のインスタンスは現行セッションで最後に生成された シーケンス値を参照します) でシーケンス番号を参照することによって可能になります。
   INSERT INTO ORDER (ORDERNO, CUSTNO)                
     VALUES (NEXT VALUE FOR ORDER_SEQ, 123456);       
   INSERT INTO LINE_ITEM (ORDERNO, PARTNO, QUANTITY)  
     VALUES (PREVIOUS VALUE FOR ORDER_SEQ, 987654, 1);
NEXT VALUE と PREVIOUS VALUE の許される使用:
NEXT VALUE と PREVIOUS VALUE 式は以下の場所に指定可能です。
  • SELECT文のSELECT句内、またはSELECT文でキーワードを含まないもの DISTINCT キーワード、 GROUP BY 節、 ORDER BY 節、または集合演算子を含まない
  • INSERT文の節内では、 VALUES INSERT文の節、複数の節を持つ複数行INSERT文、 VALUES MERGE文の挿入操作は、各節の特定のシーケンス名に対するNEXT VALUE式を含めることができます。 VALUES 節ごとに特定のシーケンス名のNEXT VALUE式を含めることができます。
  • INSERT ステートメントの全選択の select-clause 内。
  • UPDATE文の検索または位置付けの節内では、 SET 検索または位置付けられたUPDATE文の節内、MERGE文の更新操作を含め、節内の式のfullselect のselect-clauseでは NEXT VALUEを指定することはできないが SET 節の式のフルセレクトのselect-clauseでは、NEXT VALUEを指定することはできません。
    PREVIOUS VALUE式は、 SET 更新操作(UPDATEまたはMERGE文)の句でのみ使用できますが、NEXT VALUE式は SET 式の全選択の選択節内にない場合は、節に含まれません。 例えば、次のシーケンス参照の使用はサポートされます。
    UPDATE T SET C1 = (SELECT PREVIOUS VALUE FOR S1 FROM T);
    UPDATE T SET C1 = PREVIOUS VALUE FOR S1;
    UPDATE T SET C1 = NEXT VALUE FOR S1;
    次のシーケンス参照の使用はサポートされません。
    UPDATE T SET C1 = (SELECT NEXT VALUE FOR S1 FROM T);
    SET :C2 = (SELECT NEXT VALUE FOR S1 FROM T);
  • SET ホスト変数または代入文において、ただし、式のフルセレクトのselect句内を除く。
    次のシーケンス参照の使用はサポートされます。
    SET ORDERNUM = NEXT VALUE FOR INVOICE;
    SET ORDERNUM = PREVIOUS VALUE FOR INVOICE;
    次のシーケンス参照の使用はサポートされません。
    SET X = (SELECT NEXT VALUE FOR S1 FROM T);
    SET X = (SELECT PREVIOUS VALUE FOR S1 FROM T);
  • In a VALUES または VALUES INTO ステートメント内ではなく、式のフルセレクトのselect-clause 内でもない。
  • SQL プロシージャーに対する CREATE または ALTER PROCEDURE ステートメントに対する SQL-routine-body 内。
  • SQL 関数に対する CREATE FUNCTION の RETURN-statement 内。
  • CREATE TRIGGER のSQL-trigger-body 内 (PREVIOUS VALUE は許されない)。
ネスト・アプリケーションでの PREVIOUS VALUE の使用:
PREVIOUS VALUE は、アプリケーション・セッション内で線形の有効範囲をもつように定義されています。 したがって、ネスト・アプリケーション内でネストされた関数、プロシージャー、またはトリガーに入るとき、ネスト・アプリケーションはシーケンスに対して最新に生成された値を継承します。 つまり、ネスト・アプリケーション内で PREVIOUS VALUE を呼び出すと、ネスト・アプリケーションに入る前に呼び出し側の環境内で 行われていたシーケンス・アクティビティーが反映されます。 また、関数、プロシージャー、またはトリガーから戻る際に、 呼び出し側アプリケーションは下位アプリケーション内でのシーケンス・アクティビティー に影響を受けます。 つまり、ネスト・アプリケーションから戻った後、呼び出し側のアプリケーション内で PREVIOUS VALUE を呼び出すと、下位アプリケーション内で行われたシーケンス・アクティビティーが反映されます。
NEXT VALUE と PREVIOUS VALUE の使用の制限:
次のような個所では、NEXT VALUE 式と PREVIOUS VALUE 式を指定できません。
  • 完全外部結合の結合条件
  • CREATE TABLE または ALTER TABLE ステートメント内の列の DEFAULT 値
  • CREATE TABLE ステートメントまたは ALTER TABLE ステートメント内のマテリアライズ照会表の定義
  • CHECK 制約の条件
  • LOAD の入力値指定
  • CREATE VIEW ステートメント
  • NOT ATOMIC データ変更ステートメントを含む副選択の SELECT リスト
  • OLAP 指定で使用される場合の ORDER BY 節

また、次の個所では NEXT VALUE 式を指定できません。

  • CASE 式
  • 集約関数のパラメーター・リスト
  • 明示的に許可されているもの以外のコンテキスト内の副照会
  • 外部 SELECT が DISTINCT 演算子または GROUP BY 文節を含む場合の SELECT ステートメント
  • 外部 SELECT がセット演算子を使用して別の SELECT ステートメントと結合されている場合の SELECT ステートメント
  • 結合条件
  • ネストされた表の式
  • 表関数のパラメーター・リスト
  • UPDATE、DELETE、または MERGE ステートメントの SET 文節にある式の全選択の select-clause
  • 最外部 SELECT ステートメントの WHERE 節、または DELETE ステートメント、UPDATE ステートメント、または MERGE ステートメント
  • 最外部 SELECT ステートメントの ORDER BY 文節
  • 変更の開始OFFSET 節を含む全選択の選択リスト変更の終わり
  • SQL ルーチン内の IF、WHILE、DO UNTIL、または CASE ステートメント
カーソルを指定したシーケンス式の使用:
通常、SELECT NEXT VALUE FOR ORDER_SEQ FROM T1 によって作成される結果表には、シーケンス ORDER_SEQ から生成された値が、T1 から取り出した行数と同じ数だけ含まれます。 カーソルの SELECT ステートメント内で NEXT VALUE 式を参照すると、 結果表の行に対して生成された値が参照されます。 行が取り出されるたびに、シーケンス値が NEXT VALUE 式に対して生成されます。

DRDA環境でクライアント側でブロックが行われる場合、アプリケーションのFETCH文の処理前に、シーケンス値が Db2 サーバーで生成される可能性があります。 クライアント・アプリケーションが、データベースから取り出された行を必ずしもすべて明示的にフェッチしない場合、このアプリケーションは、生成されてもフェッチされていないシーケンスのこれらのすべての値 (フェッチされない行数と同じ値) をまったく認識しません。 このように生成されても取り出されていない値があると、シーケンス内でギャップが生じます。 シーケンスのこうしたギャップを防ぐことが重要な場合は、次のようにします。

  • カーソルによる制御がなくても機能し、クライアントによるブロック・フェッチが影響しない場合にのみ NEXT VALUE を使用する。
  • カーソル定義の SELECT ステートメント内で NEXT VALUE を使用する必要がある場合は、 次に説明する処置を行うことによるパフォーマンスなどへの影響と、ギャップを防ぐことのどちらが重要なのか検討してください。
    • SELECT ステートメントに対して FETCH FOR 1 ROW ONLY 文節を使用する。
    • Block fetchで説明されている他の方法でブロックフェッチを防止してみてください。
カーソルに対する PREVIOUS VALUE 式の使用:
カーソルの SELECT ステートメント内で PREVIOUS VALUE 式を参照すると、OPEN 時に評価が行われます。 つまり、カーソルの SELECT ステートメント内で PREVIOUS VALUE 式を参照すると、指定したシーケンスに対してこのアプリケーション・プロセスがカーソルのオープン前に生成した最後の値が参照されます。また、OPEN 時に評価が行われた後、 カーソルの SELECT ステートメントで PREVIOUS VALUE によって戻される値は、カーソルの SELECT ステートメントで NEXT VALUE を呼び出した場合であっても、 FETCH から FETCH の間に変化しません。 カーソルのクローズ後、PREVIOUS VALUE の値はアプリケーション・プロセスによって生成された最後の NEXT VALUE になります。

PREVIOUS VALUE は、カーソルのオープン中にカーソルの SELECT ステートメントで使用された場合、PREVIOUS VALUE の VALUE は、カーソルがオープンされる前にシーケンスに対して生成された最後の NEXT VALUE になります。 カーソルが閉じられると、PREVIOUS VALUE の値は、アプリケーション・プロセスにより生成された最後の NEXT VALUE になります。

代替構文およびシノニム:
互換性のために、キーワード NEXTVAL と PREVVAL を、それぞれ NEXT VALUE と PREVIOUS VALUE のシノニムとして使用できます。

sequence-name.NEXTVAL NEXT VALUE FOR sequence-name の代わりに指定でき、 は sequence-name.CURRVAL PREVIOUS VALUE FOR sequence-name の代わりに指定できます。

ORDER という名の表があり、ORDER_SEQ という名のシーケンスが以下のようにして作成されると仮定します。
   CREATE SEQUENCE ORDER_SEQ START WITH 1  
                          INCREMENT BY 1
                          NO MAXVALUE   
                          NO CYCLE      
                          CACHE 24      
以下の例では、NEXT VALUE 式を指定して ORDER_SEQ シーケンス番号を生成する方法を分かりやすく説明しています。
   INSERT INTO ORDER (ORDERNO, CUSTNO)                   
           VALUES (NEXT VALUE FOR ORDER_SEQ, 123456); 
   UPDATE ORDER SET ORDERNO = NEXT VALUE FOR ORDER_SEQ   
       WHERE CUSTNO = 123456;                              
   VALUES NEXT VALUE FOR ORDER_SEQ INTO :HV_SEQ;