9.12. シーケンス操作関数

本節ではPostgreSQLシーケンスオブジェクトに対し演算を行う関数について説明します。シーケンスオブジェクト(シーケンスジェネレータとも単にシーケンスとも呼ばれます)とはCREATE SEQUENCEコマンドで作成される1行の特別なテーブルです。シーケンスオブジェクトは通常テーブルの行に一意の識別子を生成するために使用されます。表9-34に列挙されているシーケンス関数は、シーケンスオブジェクトから連続したシーケンス値を取得するための、簡易でマルチユーザに対応した関数です。

表 9-34. Sequence Functions

関数戻り値説明
currval(regclass)bigint指定されたシーケンスに対しnextvalで得られた最新の値を返す
nextval(regclass)bigintシーケンスを進め、新しい値を返します。
setval(regclass, bigint)bigintシーケンスの現在値を設定する
setval(regclass, bigint, boolean)bigintシーケンスの現在値とis_calledフラグを設定する

シーケンス関数呼び出しにより操作されるシーケンスはregclass引数で指定され、そしてそれはpg_classシステムカタログ内のシーケンスのOIDに過ぎません。手作業でOIDを検索してはいけませんが、regclassデータ型の入力変換器が代わってその作業を行ってくれます。単一引用符で括られたシーケンス名を記述するだけです。そうするとそれはリテラル定数のように見えます。通常のSQLの名称での操作と互換性を取るため、文字列はシーケンス名が二重引用符で括られている以外、小文字に変換されます。よって、以下のようになります。

nextval('foo')      operates on sequence foo
nextval('FOO')      operates on sequence foo
nextval('"Foo"')    operates on sequence Foo

必要であれば、以下のようにシーケンス名をスキーマで修飾することができます。

nextval('myschema.foo')     operates on myschema.foo
nextval('"myschema".foo')   same as above
nextval('foo')              searches search path for foo

regclassに関してのより詳細な情報は項8.12を参照してください。

注意: 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を実行したとしても、それぞれのセッションは個別のシーケンス値を間違いなく受け取ります。

currval

現在のセッションにおいて、そのシーケンスからnextvalによって取得された直近の値を返します(セッション内でそのシーケンスに対しnextvalが呼ばれていない場合には、エラーが報告されます)。これはローカルのセッション値を返すことから、現在のセッションが実行してから別のセッションがnextvalを実行してもしなくても、予想に違わない回答をもたらすことに注意してください。

lastval

現在のセッションのnextvalで戻される最新の値を返します。この関数は、nextvalが現在のセッションの中で使用された最後のシーケンスの値をフェッチする引数としてのシーケンス名を取ることを除いて、currvalと同等です。現在のセッションでnextvalが未だ呼ばれていなければエラーになります。

setval

シーケンスオブジェクトの計数値をリセットします。2つのパラメータを所有する形式では、シーケンスのlast_valueフィールドを指定された値に設定し、is_calledフィールドをtrue(真)に設定します。この意味は、次のnextvalが値を返す前にシーケンスを進めるということです。3つのパラメータ形式の場合、is_calledtrue(真)もしくはfalse(偽)に設定することができます。false(偽)に設定された場合、次のnextvalが指定された正確な値を返し、シーケンスの進行は引き続くnextvalから始まります。例えば、次の例です。

SELECT setval('foo', 42);           Next nextval will return 43
SELECT setval('foo', 42, true);     Same as above
SELECT setval('foo', 42, false);    Next nextval will return 42

setvalによって返される結果は単にその第2番目の引数の値です

デフォルトのパラメータによってシーケンスオブジェクトが作成されているなら、nextvalの呼び出しで1から始まる連続的な値を返します。その他の振る舞いをCREATE SEQUENCEコマンドの特別なパラメータを使用してさせることが可能です。より詳しくはコマンドのリファレンスガイドを参照ください。

重要項目: 同一のシーケンスから数値を取得する同時実行トランザクション同士のブロックを防止するため、nextval演算は決してロールバックされません。と言うことは、たとえnextvalを実行したトランザクションが後にアボートしたとしても、値が一度取り出されたらそれは使用されたものと考えます。つまり、アボートされたトランザクションは、割り当てられた値のシーケンス内に未使用の"欠損"を残す可能性があります。いずれにしてもsetval演算は決してロールバックしません。