2014-10-28 14 views
1

我正在嘗試使用從另一個INSERT獲取的自動增量值的INSERT某些行。使用與WITH綁定的值插入數據

WITH id AS (
    INSERT INTO myTable 
     (mt_name, mt_description) 
     VALUES ('Name', 'Description') 
     RETURNING id 
) 
INSERT INTO anotherTable 
    (at_id, at_foo, at_bar) 
    VALUES (id, 'PLT', 50682), 
      (id, 'PLT', 54482), 
      (id, 'PLT', 52570), 
      (id, 'PLT', 9192); 

我很期待是INSERT一堆與at_id列行具有由第一INSERT返回的值。但是當我運行這個時,我得到:

psql:file.txt:100: ERROR: column "id" does not exist 
LINE 9: VALUES (id, 'PLT', 50682), 

是否可以通過這種方式插入返回值?如果是這樣,我必須做出什麼樣的改變才能使其發揮作用?

我使用的是Postgres 9.3.5。客戶端和服務器具有相同的版本。

回答

2

試試這個:

WITH id AS (
    INSERT INTO myTable 
     (mt_name, mt_description) 
     VALUES ('Name', 'Description') 
     RETURNING id 
) 
INSERT INTO anotherTable(at_id, at_foo, at_bar) 
SELECT id.id, 'PLT', val.v 
    FROM (VALUES (50682),(54482),(52570),(9192)) val(v) 
CROSS JOIN id; 
1

改變你這樣的查詢

WITH id AS (
    INSERT INTO myTable 
     (mt_name, mt_description) 
     VALUES ('Name', 'Description') 
     RETURNING id 
) 
INSERT INTO anotherTable 
    select id,'PLT', 50682 from id; 
+0

並沒有真正擴展到插入多個值,雖然,這是至關重要的位置。 – Kat 2014-10-28 05:10:07

1

如下表定義:

create table myTable 
(
    id serial, 
    mt_name text, 
    mt_description text 
); 

create table anotherTable 
(
    at_id serial, 
    at_foo text, 
    at_bar text 
); 

您可以通過UNNEST插入你在一個INSERT聲明中列出的項目的荷蘭國際集團的ARRAY,即:

WITH id_res AS (
    INSERT INTO myTable 
     (mt_name, mt_description) 
     VALUES ('Name', 'Description') 
     RETURNING * 
) 
INSERT INTO anotherTable 
    select id, 'PLT', unnest(ARRAY[50682, 54482, 52570, 9192]) FROM id_res; 

SQL Fiddle

注意,我改變了CTERETURNING *因此整個行將被訪問,但可以改回只id如果你將永遠不會有任何其他列的任何使用)。

而且,我改名比id其他CTE的東西,使代碼更清楚這是列,這是名臨時表,而不是完全由句法位置。否則,查詢的格式爲SELECT id from id。響應

編輯從OP評論:

複雜查詢可以得到幾分凌亂,根據不同的情況,但也有許多方法可以幫助減輕...

對於不同的值在第二列中,您始終可以使用完全獨立的查詢,即(SELECT name from names where id = 10)或其他行。

如果是更復雜的是,你可以拖放使用CTE的,而是使用一個臨時表,所以它的整個會話使用,而不只是一個查詢(一CTE本質上是一個臨時表限定爲單個查詢)。然後,您可以將複雜的查詢拆分爲多個臨時表,然後執行最後的INSERT或其他行,但仍可以訪問第一個INSERTid值。

如果mt_description列表是非常大的,你可以通過動態生成的SQL ,比方說,的Python或類似的降低複雜性,所以你並不需要手動鍵入出整個ARRAY內容。

特別是如果動態生成SQL,我不明白爲什麼上述樣式會過於混亂,即使有大量數據。 Postgres非常樂意處理看似(對人眼)巨大的疑問。例如,我已動態生成查詢,該查詢在WHERE子句中的IN列表中包含數千個項目,並且由於它是動態生成的,因此不會特別雜亂,並且在這些情況下可以很好地執行。

+0

如果插入的實際數據很複雜(多個字段和「PLT」不總是「PLT」),那麼這會變得非常混亂。 – Kat 2014-10-28 05:10:52