sql >> データベース >  >> RDS >> PostgreSQL

同じINSERT中の別の列のシリアル列の参照値

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



    1. PostgresENUMデータ型またはCHECKCONSTRAINT?

    2. 不正な指示:Djangoを実行している場合は4

    3. OracleのCOLLATION()関数

    4. SQLite-テーブルを作成する