本節ではシーケンスオブジェクトに対し演算を行う関数について説明します。 シーケンスオブジェクトは、シーケンスジェネレータ、あるいは単にシーケンスとも呼ばれます。 シーケンスオブジェクトは特殊な一行だけのテーブルで、CREATE SEQUENCEで作成されます。 シーケンスオブジェクトは一般的にテーブルの行に一意の識別子を生成するために使用されます。 表 9.47に列挙されているシーケンス関数は、シーケンスオブジェクトから連続したシーケンス値を取得するための、簡易でマルチユーザに対応した関数です。
表9.47 シーケンス関数
| 関数 | 戻り値 | 説明 |
|---|---|---|
| bigint | 指定されたシーケンスに対しnextvalで得られた最新の値を返す |
| bigint | すべてのシーケンスに対してnextvalにより最も最近取得された値を返す |
| bigint | シーケンスを進め、新しい値を返す |
| bigint | シーケンスの現在値を設定する |
| bigint | シーケンスの現在値とis_calledフラグを設定する |
シーケンス関数により操作されるシーケンスはregclass引数で指定されますが、それはpg_classシステムカタログ内にある、そのシーケンスの単なるOIDです。
しかしながら、手作業でOIDを検索する必要はなく、regclassデータ型の入力変換器が代わってその作業を行ってくれます。
単一引用符で括られたシーケンス名を記述するだけで良いので、リテラル定数のように見えます。
通常のSQLの名称での操作との互換のため、文字列はシーケンス名が二重引用符で括られていなければ、小文字に変換されます。
よって、以下のようになります。
nextval('foo') シーケンスfooの操作
nextval('FOO') シーケンスfooの操作
nextval('"Foo"') シーケンスFooの操作
必要であれば、以下のようにシーケンス名をスキーマで修飾することができます。
nextval('myschema.foo') myschema.fooの操作
nextval('"myschema".foo') 上と同じ
nextval('foo') fooを検索パスで探す
regclassに関してのより詳細な情報は8.19を参照してください。
PostgreSQLの8.1より前においては、シーケンス関数の引数はregclass型ではなく、text型で、そして上記のテキスト文字列からOID値への変換はそれぞれの呼び出し実行時に起こりました。
後方互換性のため、この仕組みはまだ存在しますが、内部的には関数が実行される前にtextからregclassへの暗黙的強制型変換として現在処理されています。
ありのままのリテラル文字列としてシーケンス関数の引数を記述すると、regclassデータ型の定数になります。
これは単なるOIDなので、後で名前付けが再び行われたとか、スキーマの再割り振りとかに関わらず、最初に特定されたシーケンスを引き継ぎます。
この「初期束縛」の動作は、列のデフォルトやビューからシーケンスを参照する場合は望ましいことが多いでしょう。
しかし、実行時にシーケンス参照が解決されるような「動的束縛」が望まれる場合もあります。
動的束縛の動作を得るには、その定数をregclassではなくtext定数として保存させます。
nextval('foo'::text) foo is looked up at runtime
PostgreSQLのリリース8.1より前では動的束縛のみがサポートされる動作だったので、旧来のアプリケーションのセマンティクスを保ちたい場合このようにする必要があるかもしれません。
もちろん、シーケンス関数の引数は定数だけでなく、評価式とすることも可能です。 テキスト式の場合は暗黙的型変換により、実行時検索が行われます。
使用できるシーケンス関数には以下のものがあります。
nextval
シーケンスオブジェクトをその次の値に進め、その値を返します。
これは原子的に処理され、複数のセッションが同時にnextvalを実行したとしても、それぞれのセッションは異なるシーケンス値を安全に受け取ります。
デフォルトのパラメータによってシーケンスオブジェクトが作成されているなら、引き続くnextval呼び出しは1から始まる連続的な値を返します。
その他の動作をCREATE SEQUENCEコマンドの特別なパラメータを使用してさせることが可能です。より詳しくはコマンドのリファレンスガイドを参照ください。
同一のシーケンスから数値を取得する同時実行トランザクション同士のブロックを防止するため、nextval演算は決してロールバックされません。
つまり、値が一度取り出されたら、それは使用されたものと見なされ、同じ値が再び返されることはありません。
これは、それを取り囲むトランザクションが後にアボートした場合でも、あるいは呼び出し側の問い合わせがその値を使用せずに終わった場合でも当てはまります。
例えばON CONFLICT句のあるINSERTでは、挿入される予定のタプルについて、必要となるすべてのnextvalの呼び出しも含めて計算し、その後でON CONFLICTのルールを代わりに使用することになる競合について検知します。
このような場合には、割り当てられた値のシーケンス内に未使用の「欠損」を残すことになります。
従って、PostgreSQLのシーケンスオブジェクトは「欠番のない」シーケンスを得るために使うことはできません。
この関数はシーケンスについてUSAGEまたはUPDATE権限を必要とします。
currval
現在のセッションにおいて、そのシーケンスからnextvalによって取得された直近の値を返します。
(セッション内でそのシーケンスに対しnextvalが呼ばれていない場合には、エラーが報告されます。)
これはセッションごとの個別の値を返すので、現在のセッションがnextvalを実行した後、他のセッションがnextvalを実行したかどうかに関わらず、期待通りの回答をもたらします。
この関数はシーケンスについてUSAGEまたはSELECT権限を必要とします。
lastval
現在のセッションのnextvalで直近に戻された値を返します。
この関数はcurrvalと同等ですが、引数としてシーケンス名をとる代わりに、現在のセッションで最後にnextvalで使用されたシーケンスを参照するところが異なります。
現在のセッションでnextvalが未だ呼ばれていなければエラーになります。
この関数は、最後に使用したシーケンスについてUSAGEまたはSELECT権限を必要とします。
setval
シーケンスオブジェクトの計数値をリセットします。
パラメータが2つの形式では、シーケンスのlast_valueフィールドを指定された値に設定し、is_calledフィールドをtrue(真)に設定します。
この意味は、次のnextvalが値を返す前にシーケンスを進めるということです。
currvalで報告される値も指定された値に設定されます。
3パラメータ形式の場合、is_calledをtrue(真)もしくはfalse(偽)に設定することができます。
true(真)は2パラメータ形式と同じ効果があります。
false(偽)に設定された場合、次のnextvalは指定されたその値を返し、シーケンスの進行は引き続くnextvalから始まります。
さらにこの場合、currvalで報告される値は変更されません。
例えば、次の例です。
SELECT setval('foo', 42); 次のnextvalは43を返す
SELECT setval('foo', 42, true); 上と同じ
SELECT setval('foo', 42, false); 次のnextvalは42を返す
setvalによって返される結果は単にその第2番目の引数の値です。
シーケンスはトランザクションとは異なる扱いを受けるため、setvalによる変更は、そのトランザクションがロールバックされたとしても元に戻りません。
この関数はシーケンスについてUPDATE権限を必要とします。