2014-10-28 36 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