【问题标题】:Insert the result of an insert into another table将插入的结果插入到另一个表中
【发布时间】:2014-04-29 10:49:58
【问题描述】:

对于 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)
);

要插入事件,我必须先插入事件详细信息,然后再插入“通用”事件,并与事件详细信息链接。我已经建立了这个查询来做到这一点:

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”处或附近的语法错误

所以我不能像使用SELECT 那样插入带有INSERT INTO 的值。如何将新创建的row 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 提供此解决方案!

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    您必须将查询分开,因为插入子查询不是有效的值表达式:

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

    或者你可以创建一个存储过程。这样可以减少开销。

    【讨论】:

    • 您不应链接(或使用)完全过时版本的手册。查看 Jaffar 的回答,这在当前的 Postgres 版本中确实是可能的。
    • 好吧,对不起,它没有改变想法。我更新了链接,仍然不允许插入作为表达式值。
    • 你看到贾法尔的回答了吗?
    【解决方案2】:

    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 实际上是单行值,这很有意义。

    【讨论】:

    • WITH ... AS ... 解决方案的作用就像一个魅力。谢谢!我的查询现在看起来像: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));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多