2017-08-29 60 views
0

我創建了這兩個表:如何獲得子表的外鍵具有相同的值作爲父母的首要自動增量鍵

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

您可以使用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

+0

這些都工作完美:)是否有任何優勢使用非此即彼? –

+0

@IvanLendl'lastval()'只有在兩次插入之間的事務中沒有發生任何事情時纔會起作用。否則,他們三人的工作原理是一樣的 - 這是個人品味的問題 –

+0

如果我想放入一個不屬於序列的屬性,該怎麼辦?那麼我怎樣才能從一張桌子到另一張桌子呢? –

1

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,不服像

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 
+0

如何訪問_the_value_above_爲purchaseID?我正在通過postgres客戶端運行它:psequel。不確定如何在下一個語句中使用返回的purchaseid。 –

+0

我也不明白最後一部分,與DO塊。這是如何運作的? –

+0

返回purchaseID將顯示值,就好像你選擇,所以只是複製粘貼它 –

相關問題