使用WITH绑定的值插入数据

时间:2014-10-28 04:17:30

标签: sql postgresql

我正在尝试使用从另一个INSERT获取的自动增量值INSERT某些行。

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。客户端和服务器具有相同的版本。

3 个答案:

答案 0 :(得分: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 :(得分: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;

答案 2 :(得分:1)

鉴于以下表格定义:

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

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

您可以INSERT UNNEST 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; 声明中列出的所有项目,即:

RETURNING *

SQL Fiddle

注意我已将 CTE 更改为id,因此可以访问整行,但如果您永远无法使用,则可以将其更改回id任何其他专栏)。

此外,我将 CTE 重命名为SELECT id from id以外的其他内容,因此代码更清晰,即列,并且是名称的临时表,而不仅仅是语法位置。否则,查询的格式为(SELECT name from names where id = 10)

根据OP的评论进行编辑:

根据具体情况,复杂查询可能会变得混乱,但有很多方法可以帮助减轻这种情况......

对于第二列的不同值,您始终可以使用完全独立的查询,即INSERT或沿着这些行的某些内容。

如果它仍然比较复杂,你可以放弃使用 CTE ,而是使用临时表,这样它就可以使用整个会话而不仅仅是那一个查询( CTE 本质上是一个作用于单个查询的临时表)。然后,您可以将复杂查询拆分为多个临时表,然后执行最终INSERT或其他内容,同时仍然可以访问第一个id {{1} }值。

如果mt_description列表非常大,您可以通过动态生成 Python 中的 SQL 来降低复杂性,所以你不要#39; t需要手动输入整个ARRAY内容。

特别是如果动态生成SQL,我不明白为什么上述样式会过于混乱,即使有大量数据也是如此。 Postgres 非常乐意处理看似(对人眼)巨大的疑问。例如,我动态生成的查询在IN子句中的WHERE列表中包含数千个项目,并且由于它是动态生成的,因此不是特别混乱, Postgres 在这些情况下表现良好。