将插入的结果插入另一个表中

时间:2014-03-21 21:00:12

标签: sql postgresql

使用PostgreSQL,给出以下表格:

CREATE TABLE events (
  id BIGSERIAL PRIMARY KEY,
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
);

CREATE TABLE event_details (
  uuid UUID NOT NULL,
  signal_strength SMALLINT NOT NULL,
  event_id INTEGER REFERENCES events (id) ON DELETE RESTRICT,
  PRIMARY KEY (event_id)
);

要插入事件,我必须先插入事件详细信息,然后插入" generic"事件之后,与事件详细信息链接。我已经构建了这个查询来执行此操作:

INSERT INTO event_details VALUES ('B9056867-459D-4F0B-8627-7456C880F54B', 50, (INSERT INTO events VALUES (DEFAULT, '2014-03-21 15:37:44.683081-04') RETURNING id));

但我收到此错误: 错误:语法错误在或接近" INTO"

所以我无法插入INSERT INTO的值,就像使用SELECT一样。如何将新创建的行id转发到event_details的外键列?

当系统运行时,可能会有很多这些查询,所以我想避免在我的代码中(在NodeJS中)检索id,然后在单独的语句中执行第二个INSERT

谢谢!

PS:我简化了表的SQL,但我有一些很好的理由将event_details与事件分开(有许多事件类型具有不同的细节)。

[编辑]

在这种情况下,正确的方法是:

WITH new_event AS (INSERT INTO events VALUES (DEFAULT, '2014-03-21 15:37:44.683081-04') RETURNING id) INSERT INTO event_details VALUES ('B9056867-459D-4F0B-8627-7456C880F54B', 50, (SELECT id FROM new_event LIMIT 1));

感谢Jaffar的answer提供此解决方案!

2 个答案:

答案 0 :(得分:1)

PostgreSQL对VALUES子句有如此扩展的解释,它可以单独用作子查询。

所以你可以用这种形式表达你的疑问:

WITH new_invoice AS (
    INSERT INTO ...
    RETURNING id
),
v(a,b,c,d) AS (values
  ($27,$28,$29,$30),
  ($31,$32,$33,$34),
  ...
)
INSERT INTO invoiceItems (invoice_id, name, qty, price, description)
 SELECT new_invoice.id, a,b,c,d FROM v, new_invoice;

假设您要插入new_invoice的笛卡尔积和值,如果new_invoice实际上是单行值,则这些值最有意义。

答案 1 :(得分:0)

您必须分隔查询,因为insert-subquery不是有效的值表达式:

http://www.postgresql.org/docs/9.3/static/sql-expressions.html

或者您可以制作存储过程。这减少了开销。