CTEを使用して、シーケンスから値を1回取得できます。 繰り返し使用します :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
データ変更コマンドを使用するCTEには、Postgres9.1以降が必要です。
シーケンスの名前がわからない場合は、pg_get_serial_sequence()
を使用してください。 代わりに:
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
テーブル名「foo」がDB内のすべてのスキーマで一意でない可能性がある場合は、スキーマ修飾します。また、名前のスペルが標準的でない場合は、二重引用符で囲む必要があります。
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
クイックテストでは、@Markのアイデアがlastval()
で示されました かもしれない 仕事も:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
id
のままにしておくことができます クエリのうち、serial
列は自動的に割り当てられます。違いはありません。 -
行間に競合状態があってはなりません。マニュアルを引用します:
currval
nextval
によって最後に取得された値を返します 現在のセッションのこのシーケンス。 (nextval
の場合、エラーが報告されます このセッションでは、このシーケンスに対して呼び出されたことはありません。)これはセッションローカル値を返すため、他のセッションがnextval
を実行したかどうかに関係なく予測可能な回答が得られます。 現在のセッション以降この関数には
USAGE
が必要です またはSELECT
シーケンスの特権。
lastval
nextval
によって最後に返された値を返します 現在のセッションで。この関数はcurrval
と同じです 、ただし シーケンス名を引数として使用する代わりに、nextval
のシーケンスを参照します。 現在のセッションで最後に適用されました。lastval
を呼び出すとエラーになります。nextval
の場合 現在のセッションではまだ呼び出されていません。この関数には
USAGE
が必要です またはSELECT
最後に使用されたシーケンスに対する特権。
大胆な強調鉱山。
しかし 、@ Bernardがコメントしたように、結局失敗する可能性があります。デフォルト値が満たされる保証はありません(およびnextval()
プロセスで呼び出されます)前 lastval()
2番目の列を埋めるために呼び出されますltree
。したがって、最初の解決策とnextval()
に固執します 確かに。