ส่วนคำสั่ง 'return' สามารถส่งคืนคอลัมน์ต้นทางที่ไม่ได้แทรกได้หรือไม่?


14

นี่คือตัวอย่างเล็กน้อยของปัญหาจริงของฉัน:

create table t(id serial primary key, rnd double precision);

แน่นอนคุณสามารถส่งคืนคอลัมน์ที่แทรกด้วยreturningประโยค:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *;
/*
| ID |            RND |
|----|----------------|
|  9 | 0.203221440315 |
*/

คุณสามารถคืนค่าตัวอักษร:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, 1.0 dummy;
/*
| ID |            RND | DUMMY |
|----|----------------|-------|
| 11 | 0.594980469905 |     1 |
*/

แต่คุณไม่สามารถคืนคอลัมน์ต้นฉบับได้:

with w as (insert into t(rnd) values(random()) returning *)
insert into t(rnd) select random() from w returning *, w.rnd;
/*
ERROR: missing FROM-clause entry for table "w": with w as (insert into t(rnd) values(random()) returning *) insert into t(rnd) select random() from w returning *, w.rnd
*/

มีวิธีใดบ้างที่ฉันจะw.rndออกจากreturningประโยคสุดท้าย?

db <> ซอที่นี่


ใน MS SQL Server เฉพาะคำสั่ง MERGE จะอนุญาตให้ส่งคืนคอลัมน์เพิ่มเติม บางทีนั่นอาจใช้ได้กับ postgres ด้วย
เซบาสเตียนมีน

ฉันแก้ไขปัญหาที่คล้ายกันสำหรับUPDATEในคำตอบที่เกี่ยวข้องใน SOแต่ไม่สามารถทำงานINSERTได้
Erwin Brandstetter

คำตอบ:


12

เอกสารเกี่ยวกับRETURNINGข้อกล่าวว่า:

นิพจน์ที่ต้องคำนวณและส่งคืนโดยคำสั่ง INSERT หลังจากแทรกแต่ละแถวแล้ว นิพจน์สามารถใช้ชื่อคอลัมน์ใด ๆ ของตารางที่ตั้งชื่อโดย table_name เขียน * เพื่อกลับคอลัมน์ทั้งหมดของแถวที่แทรก

สิ่งนี้ไม่ชัดเจนสำหรับคอลัมน์จากตารางอื่น

แม้ว่าฉันจะไม่เข้าใจปัญหาจริง ๆ (นั่นคือสาเหตุที่คุณทำเช่นนี้ - ฉันคิดว่าเป็นเพราะมันเป็นเวอร์ชั่นดั้งเดิมที่ค่อนข้างนามธรรมเกินไป) วิธีแก้ไขที่เป็นไปได้คือ:

WITH w AS (INSERT INTO t(rnd) VALUES (random()) RETURNING *),
     x AS (INSERT INTO t(rnd) SELECT random() FROM w RETURNING *)
SELECT w.rnd, x.rnd
  FROM w, x;

นั่นคือคุณสามารถใส่ CTE ที่เขียนได้มากกว่าหนึ่งรายการไปยังจุดเริ่มต้นของแบบสอบถาม โปรดดูนี้ในการดำเนินการเกี่ยวกับdbfiddle

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.