สิ่งนี้เป็นสิ่งที่คาดหวังพฤติกรรมของเอกสาร
ทอมเลนอธิบายไว้ที่นี่
เอกสารในคู่มือที่นี่:
คำสั่งในการปรับเปลี่ยนข้อมูลWITHจะถูกดำเนินการเพียงครั้งเดียวและ
ดำเนินการให้เสร็จสิ้นเสมอโดยไม่ขึ้นอยู่กับว่าข้อความค้นหาหลักอ่านผลลัพธ์ทั้งหมดของพวกเขาหรือไม่ แจ้งให้ทราบว่าเรื่องนี้จะแตกต่างจากกฎสำหรับSELECTในWITH: ตามที่ระบุไว้ในส่วนก่อนหน้านี้การดำเนินการจะดำเนินการเพียงเท่าที่แบบสอบถามหลักเรียกร้องเอาท์พุทSELECT
เหมืองเน้นหนัก "ข้อมูลการปรับเปลี่ยน" เป็นINSERT, UPDATEและDELETEคำสั่ง (ตรงข้ามกับSELECT.) คู่มืออีกครั้ง:
คุณสามารถใช้งบข้อมูลการปรับเปลี่ยน ( INSERT, UPDATEหรือDELETE) WITHใน
ฟังก์ชั่นที่เหมาะสม
CREATE OR REPLACE FUNCTION public.__post_users_id_coin (_coins integer, _userid integer)
RETURNS TABLE (id integer) AS
$func$
UPDATE users u
SET coin = u.coin + _coins -- see below
WHERE u.id = _userid
RETURNING u.id
$func$ LANGUAGE sql COST 100 ROWS 1000 STRICT;
ฉันลดลงเริ่มต้น (เสียง) และคำสั่ง
เป็นคำพ้องความหมายสั้นSTRICT ๆRETURNS NULL ON NULL INPUT
ตรวจสอบให้แน่ใจว่าชื่อพารามิเตอร์นั้นไม่ขัดแย้งกับชื่อคอลัมน์ ฉันเติมด้วย_แต่นั่นเป็นเพียงความชอบส่วนตัวของฉัน
ถ้าฉันcoinสามารถNULLแนะนำ:
SET coin = CASE WHEN coin IS NULL THEN _coins ELSE coin + _coins END
ถ้าusers.idเป็นคีย์หลักแล้วค่าRETURNS TABLEมิได้ROWs 1000ทำให้รู้สึกใด ๆ สามารถอัพเดต / ส่งคืนได้เพียงแถวเดียว แต่นั่นคือทั้งหมดที่อยู่ข้างจุดหลัก
โทรเหมาะสม
ไม่มีเหตุผลที่จะใช้ส่วนRETURNINGคำสั่งและค่าส่งคืนจากฟังก์ชันของคุณหากคุณจะเพิกเฉยกับค่าที่ส่งคืนในการโทรอยู่ดี นอกจากนี้ยังไม่มีเหตุผลที่จะแยกย่อยแถวที่ส่งคืนด้วยSELECT * FROM ...หากคุณไม่สนใจ
เพียงแค่คืนค่าสเกลาร์สเกลาร์ ( RETURNING 1) กำหนดฟังก์ชันเป็นRETURNS int(หรือปล่อยRETURNINGพร้อมกันแล้วทำRETURNS void) และเรียกมันด้วยSELECT my_function(...)
วิธีการแก้
ตั้งแต่คุณ ...
ไม่สนใจผลลัพธ์
.. เพียงแค่SELECTรูปแบบคงที่ CTE มันรับประกันว่าจะถูกดำเนินการตราบใดที่มีการอ้างอิงในด้านนอกSELECT(โดยตรงหรือโดยอ้อม)
WITH test AS (SELECT __post_users_id_coin(10, 1))
SELECT 1 FROM test;
หากคุณมีฟังก์ชั่นset-returnและยังไม่สนใจเอาต์พุต:
WITH test AS (SELECT * FROM __post_users_id_coin(10, 1))
SELECT 1 FROM test LIMIT 1;
ไม่จำเป็นต้องส่งคืนมากกว่า 1 แถว ฟังก์ชั่นยังคงเรียกว่า
ในที่สุดก็ไม่มีความชัดเจนว่าทำไมคุณต้องเริ่มต้น CTE อาจเป็นเพียงการพิสูจน์แนวคิด
ที่เกี่ยวข้องอย่างใกล้ชิด:
คำตอบที่เกี่ยวข้องกับ SO:
และพิจารณา: