DELETE/INSERT/UPDATE แบบมีเงื่อนไขใน MERGE

ฉันเจอสองตัวอย่างเกี่ยวกับ MERGE ที่มี DML แบบมีเงื่อนไข

ตัวอย่างแรก,

MERGE INTO bonuses D
   USING (SELECT employee_id, salary, department_id FROM employees
   WHERE department_id = 80) S
   ON (D.employee_id = S.employee_id)
   WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
     DELETE WHERE (S.salary > 8000)
   WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
     VALUES (S.employee_id, S.salary*.01)
     WHERE (S.salary <= 8000);

ฉันมักจะเข้าใจว่าใน MERGE มีการแก้ไขเฉพาะตารางเป้าหมาย (D ที่นี่) เมื่อเราใส่ DML ใน WHEN มันจะทำงานบนตารางเป้าหมาย D ดังนั้นในกรณีนี้ เงื่อนไขเกี่ยวข้องกับ S อย่างไร ดังเช่นในส่วนคำสั่ง DELETE และ UPDATE WHERE จะเริ่มดำเนินการเมื่อใด ? หลังการจับคู่ ? บนแหล่งที่มา/เป้าหมายก่อน ON ?

อีกตัวอย่างที่เกี่ยวข้อง พร้อมอีกหนึ่งคำถาม

MERGE INTO destination d
  USING source s
    ON (s.id = d.id)
  WHEN MATCHED THEN
    UPDATE SET  d.description = 'Updated',
                d.status = 10
    DELETE WHERE s.status = 10;

และ

MERGE INTO destination d
  USING source s
    ON (s.id = d.id)
  WHEN MATCHED THEN
    UPDATE SET  d.description = 'Updated',
                d.status = 10
    DELETE WHERE d.status = 10;

ฉันไม่ได้รับความแตกต่างระหว่าง 2 สถานการณ์: ตารางแหล่งที่มาและเป้าหมายในส่วนคำสั่ง WHERE

ขอบคุณล่วงหน้า.


person Kenny    schedule 22.04.2016    source แหล่งที่มา


คำตอบ (2)


การดำเนินการ MERGE มีสองส่วน: จะต้องดำเนินการอย่างไร (อัปเดตบางประเภท รวมถึงการแทรกและการลบ) ซึ่งจะอยู่ในตารางเป้าหมายเท่านั้น และเมื่อใดที่จะดำเนินการ - เงื่อนไขใดที่ต้องปฏิบัติตามเพื่อเริ่มการอัปเดต เงื่อนไขต้องอ้างอิงถึงบางสิ่งในตารางเป้าหมาย แต่ยังอ้างอิงถึงตารางต้นฉบับด้วย

ในตัวอย่างแรกของคุณ: ตารางเป้าหมายมีเพียงรหัสพนักงานและค่าตีกลับเท่านั้น คุณต้องการเพิ่มโบนัสแต่ละรายการ 1% ของเงินเดือนพื้นฐานสำหรับพนักงานแต่ละคน และเพิ่มโบนัส (เมื่อไม่มีแถวสำหรับพนักงานคนนั้น) สำหรับพนักงานที่ไม่ได้รับโบนัสเลย ดังนั้นคุณไม่เพียงแต่ดูตารางเป้าหมายเท่านั้น แต่ยังต้องดูที่อื่นด้วยที่เก็บเงินเดือนไว้ด้วย ในกรณีนี้ "เมื่อตรงกัน" ตรวจสอบให้แน่ใจว่าคุณดูรหัสพนักงานเดียวกันในทั้งสองตาราง จากนั้นคุณเพิ่มโบนัส 1% ของเงินเดือนพื้นฐาน เงินเดือนพื้นฐานอ่านได้จากตารางต้นฉบับ จากนั้นคุณลบโบนัสทั้งหมด (จะไม่มีแถวสำหรับรหัสพนักงานในตารางโบนัส) หากพนักงานมีฐานเงินเดือนมากกว่า 80,000 - นั่นจะต้องเป็นการตัดสินใจทางธุรกิจที่สะท้อนให้เห็นในฐานข้อมูล ดังนั้นคุณจะเห็นได้ว่าคุณต้องอ้างอิงข้อมูลในตำแหน่งอื่นที่ไม่ใช่ตารางเป้าหมายอย่างไร แม้ว่าการเปลี่ยนแปลงจะส่งผลต่อเป้าหมายเท่านั้นก็ตาม

ในตัวอย่างที่สองของคุณ ผลลัพธ์จะเหมือนเดิม

person mathguy    schedule 22.04.2016

ในตัวอย่างแรก 1. มีการระบุพนักงานที่อยู่ในแผนก 80 พนักงานเหล่านี้อาจมีหรือไม่มีบันทึกโบนัสเทียบกับรหัสพนักงานในตารางโบนัส 2. หากมีโบนัสอยู่แล้วในโบนัส ให้เพิ่มโบนัสในโบนัสสำหรับพนักงานรายนี้ 1 เปอร์เซ็นต์ของเงินเดือน หลังจากนั้น หากเงินเดือนของพนักงานมากกว่า 8,000 เขาจะต้องไม่มีโบนัส ดังนั้นให้ลบบันทึกโบนัสของเขาออกจากโบนัส 3. หากไม่มีโบนัสอยู่แล้ว และหากเงินเดือนพนักงานไม่เกิน 8000 ให้เพิ่มบันทึกโบนัสใหม่

ลำดับในกรณีนี้เพื่อวัตถุประสงค์ในการทำความเข้าใจจะเป็น ON เมื่อจับคู่แล้ว อัปเดต โดยที่ ลบ เมื่อไม่ตรงกัน โดยที่ แทรก

ในตัวอย่างที่สอง แบบสอบถาม 1: หากมีเรกคอร์ดต้นทางอยู่ที่ปลายทาง ก. อัปเดตคำอธิบายและสถานะปลายทาง ข. จากนั้นหากสถานะต้นทางเป็น 10 ให้ลบบันทึกที่มีรหัสเดียวกันจากปลายทาง

แบบสอบถาม 2: หากมีบันทึกต้นฉบับอยู่ที่ปลายทาง ก. อัปเดตคำอธิบายและสถานะปลายทาง ข. จากนั้นลบบันทึกนั้นออกจากปลายทาง

ในการอัปเดต query2 นั้นซ้ำซ้อน เว้นแต่ว่าจะมีทริกเกอร์อัปเดตตารางอื่น

ลำดับในกรณีนี้เพื่อจุดประสงค์ในการทำความเข้าใจจะเป็น ON เมื่อจับคู่แล้วอัปเดต WHERE ลบ

หวังว่านี่จะช่วยได้

person ArtBajji    schedule 22.04.2016