2016-04-17 22 views
0

PostgreSQL 9.5データベースでは、DAG内で相互に関連する異なるタイプのオブジェクト(それぞれ独自のテーブルに格納されています)があります。このDAGを表すために、私はnodeedgeテーブルを設定しました。Postgres:WITHステートメントを持つSELECTクエリの結果を挿入します。

CREATE TABLE node (
    id SERIAL PRIMARY KEY NOT NULL 
); 

はのは、私のオブジェクトの種類のいずれかが表libraryであるとしましょう:node表には、単にオブジェクトを格納するすべてのテーブルで共有されるグローバルに一意なIDが格納されます。他のフィールドを無視して、この表は単に:

CREATE TABLE library (
    uuid INTEGER NOT NULL REFERENCES node(id), 
    id TEXT PRIMARY KEY NOT NULL 
) 

次のように私はlibraryにID XXX有する単一のエントリをロードすることができる:

WITH x AS (
    INSERT INTO node (id) VALUES (DEFAULT) RETURNING id 
) 
INSERT INTO library (id, uuid) VALUES ('XXX', (SELECT id FROM x)); 

しかし、私は、外部リソースを参照するビューimport.libraryを有します、そのビューからpublic.libraryen masseをロードします。データ修正WITH文は、トップレベルにあるため、可能ではない

INSERT INTO library (uuid, id) 
    WITH x AS (
    INSERT INTO node (id) VALUES (DEFAULT) RETURNING id 
) 
    SELECT (SELECT id FROM x), id FROM import.library; 

:つまり、私はこのような何かをしたいです。

私はDO文で匿名関数を使用して同じ結果を得ることができます:これは動作します

DO $$DECLARE l_id TEXT; 
BEGIN 
    FOR x IN SELECT id FROM import.library 
    LOOP 
    WITH x AS (
     INSERT INTO node (id) VALUES (DEFAULT) RETURNING id 
    ) 
    INSERT INTO library (id, uuid) VALUES (l_id, (SELECT id FROM x)); 
    END LOOP; 
END$$; 

が、私はまだそれがない単純なSQL文で同じことを行うことは可能ですかどうかを知りたいのですが無名の機能に頼っている。

答えて

2

nodeテーブル内のUUIDは、シーケンスによって生成されるように、私は考えることができる唯一の方法は、挿入の順序を反転することです:

WITH x AS (
    INSERT INTO library (uuid, id) 
    SELECT nextval('node_id_seq'), id 
    FROM import_library 
    returning uuid 
) 
INSERT INTO node (id) 
select uuid 
from x 
+0

@wjv:本当に外に考えている私の編集 –

+0

を見ますボックス!うん、それはそのトリックをするようだから、私はそれを受け入れるつもりだ...ありがとう! – wjv

関連する問題