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()に固執します 確かに。