我创建了这两个表:
CREATE TABLE Purchase(
purchaseID SERIAL,
custName VARCHAR(30) NOT null,
PRIMARY KEY (purchaseID));
CREATE TABLE PurchasedItem(
purchaseID INT,
itemNo INT NOT NULL,
PRIMARY KEY (purchaseID, itemNo),
FOREIGN KEY (purchaseID) REFERENCES Purchase(purchaseID));
接下来我希望将数据插入到两个表中,所购买商品的purchaseID外键与购买表中的purchaseID Serial具有相同的值。
我正在使用名为PSequel的PostgreSQL客户端。我尝试在客户端首先将AUTOCOMMIT设置为关闭,这样我就可以在同一个事务中使用两个INSERT语句,但是客户端没有识别" autocommit",所以我在终端中尝试了它而我认为它有用......无论如何,这些是我试过的两个INSERT语句。
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (DEFAULT, 111);
commit;
但是我收到错误:
ERROR: null value in column purchaseID violates not-null constraint.
这是指PurchasedItem的purchaseID,就像在运行第一个INSERT语句时一样。我该如何解决这个问题?
答案 0 :(得分:2)
DEFAULT
适用于SERIAL
,因为它为列设置了默认值。所以
INSERT INTO Purchase VALUES (DEFAULT,'Lendl');
应该有效。但是PurchasedItem.purchaseID
没有设置默认值,因此它尝试插入NULL
(并且null尚未在引用列中),因此它失败。
尝试:
INSERT INTO Purchase(custName) VALUES ('Lendl') RETURNING purchaseID;
你会看到插入purchaseID
的值,在下一个查询中使用它:
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (_the_value_above_, 111);
commit;
如果您希望在没有互动性的情况下使用它,请使用DO
阻止returning purchaseID into _value
更新:
或cte,smth like
WITH i AS (
INSERT INTO Purchase(custName, orderedDate)
VALUES ('Lendl', '2016-09-28')
RETURNING purchaseID
)
insert into PurchasedItem
select i.purchaseID,'smth',3
from i
答案 1 :(得分:0)
您可以使用lastval()
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo) VALUES (lastval(), 111);
commit;
或者直接查询基础序列:
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo)
VALUES (currval('purchase_purchaseid_seq'), 111);
commit;
或者,如果您不想依赖序列的自动命名,请使用pg_get_serial_sequence
获取与列关联的序列:
INSERT INTO Purchase(custName) VALUES ('Lendl');
INSERT INTO PurchasedItem(purchaseID, itemNo)
VALUES (currval(pg_get_serial_sequence('purchase', 'purchaseid')), 111);
commit;
有关详细信息,请参阅手册:https://www.postgresql.org/docs/current/static/functions-sequence.html