如何让子表的外键与父进程的主要自动增量键具有相同的值

时间:2017-08-29 03:11:21

标签: postgresql

我创建了这两个表:

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语句时一样。我该如何解决这个问题?

2 个答案:

答案 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