สิ่งนี้เป็นไปได้หรือไม่?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
เช่นเดียวกับการใช้ค่า return เป็นค่าเพื่อแทรกแถวในตารางที่สองโดยอ้างอิงกับตารางแรก?
สิ่งนี้เป็นไปได้หรือไม่?
INSERT INTO Table2 (val)
VALUES ((INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id));
เช่นเดียวกับการใช้ค่า return เป็นค่าเพื่อแทรกแถวในตารางที่สองโดยอ้างอิงกับตารางแรก?
คำตอบ:
คุณสามารถทำได้โดยเริ่มจาก Postgres 9.1:
with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val)
SELECT id
FROM rows
ในขณะเดียวกันหากคุณสนใจเฉพาะรหัสคุณสามารถทำได้โดยใช้ทริกเกอร์:
create function t1_ins_into_t2()
returns trigger
as $$
begin
insert into table2 (val) values (new.id);
return new;
end;
$$ language plpgsql;
create trigger t1_ins_into_t2
after insert on table1
for each row
execute procedure t1_ins_into_t2();
rows
ด้วย(some_query returning ...)
อาจใช้งานได้ในปัจจุบัน (ยังไม่ได้ลอง)
แนวทางปฏิบัติที่ดีที่สุดสำหรับสถานการณ์นี้ ใช้RETURNING … INTO
.
INSERT INTO teams VALUES (...) RETURNING id INTO last_id;
โปรดทราบว่านี่สำหรับ PLPGSQL
RETURNING ... INTO
ส่วนหนึ่งของเอกสารที่คุณเชื่อมโยงไปยังดูเหมือนว่าจะพูดถึง
สอดคล้องกับคำตอบของ Denis de Bernardy ..
หากคุณต้องการส่งคืน id ในภายหลังเช่นกันและต้องการแทรกสิ่งต่างๆเพิ่มเติมใน Table2:
with rows as (
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id
)
INSERT INTO Table2 (val, val2, val3)
SELECT id, 'val2value', 'val3value'
FROM rows
RETURNING val
DO $$
DECLARE tableId integer;
BEGIN
INSERT INTO Table1 (name) VALUES ('a_title') RETURNING id INTO tableId;
INSERT INTO Table2 (val) VALUES (tableId);
END $$;
ทดสอบกับ psql (10.3, เซิร์ฟเวอร์ 9.6.8)
คุณสามารถใช้lastval()
ฟังก์ชัน:
ส่งคืนค่าที่ได้รับล่าสุด
nextval
สำหรับลำดับใด ๆ
ดังนั้นสิ่งนี้:
INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val) VALUES (lastval());
สิ่งนี้จะทำงานได้ดีตราบเท่าที่ไม่มีใครเรียกnextval()
ลำดับอื่น ๆ (ในเซสชันปัจจุบัน) ระหว่าง INSERT ของคุณ
ดังที่เดนิสระบุไว้ด้านล่างและฉันเตือนเกี่ยวกับข้างต้นการใช้lastval()
อาจทำให้คุณมีปัญหาหากมีการเข้าถึงลำดับอื่นโดยใช้nextval()
ระหว่าง INSERT ของคุณ สิ่งนี้อาจเกิดขึ้นได้หากมีทริกเกอร์ INSERT ที่เรียกTable1
ด้วยตนเองnextval()
ตามลำดับหรือมีแนวโน้มมากขึ้นที่จะแทรกบนตารางด้วยคีย์SERIAL
หรือBIGSERIAL
คีย์หลัก หากคุณต้องการที่จะหวาดระแวงจริงๆ (เป็นสิ่งที่ดีจริงๆแล้วพวกเขาคือคุณที่จะทำให้คุณได้รับหลังจากนั้น) คุณสามารถใช้ได้currval()
แต่คุณต้องรู้ชื่อของลำดับที่เกี่ยวข้อง:
INSERT INTO Table1 (name) VALUES ('a_title');
INSERT INTO Table2 (val) VALUES (currval('Table1_id_seq'::regclass));
ลำดับที่สร้างขึ้นโดยอัตโนมัติมักจะเป็นชื่อt_c_seq
ที่t
เป็นชื่อตารางและc
เป็นชื่อคอลัมน์ แต่คุณสามารถหาโดยจะเป็นpsql
และพูดว่า:
=> \d table_name;
จากนั้นดูค่าเริ่มต้นสำหรับคอลัมน์ที่เป็นปัญหาเช่น:
id | integer | not null default nextval('people_id_seq'::regclass)
FYI: lastval()
มีมากกว่าหรือน้อยกว่ารุ่น PostgreSQL ของของ LAST_INSERT_ID
MySQL ฉันพูดถึงเรื่องนี้เพราะผู้คนจำนวนมากคุ้นเคยกับ MySQL มากกว่า PostgreSQL ดังนั้นการเชื่อมโยงlastval()
กับสิ่งที่คุ้นเคยอาจทำให้เกิดความกระจ่าง
lastval
คืออาจมี INSERT ตามลำดับที่อยู่ด้านหลังของคุณจากทริกเกอร์ AFTER INSERT บน Table1 นั่นจะอยู่ในเซสชันปัจจุบันและอาจมีการเปลี่ยนแปลงlastval()
เมื่อคุณไม่คาดหวัง
table_ex
id default nextval ('table_id_seq' :: regclass),
camp1 varchar
camp2 varchar
INSERT INTO table_ex(camp1,camp2) VALUES ('xxx','123') RETURNING id