使用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提供此解决方案!
答案 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
或者您可以制作存储过程。这减少了开销。