แม้ว่าคำถามที่ผ่านมาหลายปีผ่านไปแล้ว แต่ฉันต้องการชี้แจงให้ผู้พูดภาษาสเปนได้ทำการทดสอบใน Postgres:
มีการเพิ่มข้อ จำกัด ต่อไปนี้ลงในตารางของระเบียน 1337 ซึ่งชุดเป็นคีย์หลัก:
**Bloque 1**
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
สิ่งนี้สร้างคีย์หลักเริ่มต้นที่ไม่ได้กำหนดไว้สำหรับตารางดังนั้นเมื่อพยายามอัปเดตครั้งต่อไปเราจะได้รับข้อผิดพลาด:
update ele_kitscompletos
set div_nkit = div_nkit + 1;
ข้อผิดพลาด: คีย์ที่ซ้ำกันละเมิดข้อ จำกัด ที่ไม่ซ้ำกัน« unique_div_nkit »
ใน Postgres การดำเนินการ UPDATE สำหรับแต่ละ ROW จะตรวจสอบว่าเป็นไปตามข้อ จำกัด หรือข้อ จำกัด
ตอนนี้ CONSTRAINT IMMEDIATE ถูกสร้างขึ้นและแต่ละคำสั่งจะถูกดำเนินการแยกจากกัน:
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY IMMEDIATE
**Bloque 2**
BEGIN;
UPDATE ele_kitscompletos set div_nkit = div_nkit + 1;
INSERT INTO public.ele_kitscompletos(div_nkit, otro_campo)
VALUES
(1338, '888150502');
COMMIT;
ข้อความค้นหาตกลง, 0 แถวที่ได้รับผลกระทบ (เวลาดำเนินการ: 0 ms; เวลาทั้งหมด: 0 ms) แบบสอบถามตกลง, แถวที่ได้รับผลกระทบ 1328 แถว (เวลาดำเนินการ: 858 ms; เวลาทั้งหมด: 858 มิลลิวินาที) ข้อผิดพลาด: : Ya existe la llave (div_nkit) = (1338)
ที่นี่ SI อนุญาตให้เปลี่ยนคีย์หลักเนื่องจากเรียกใช้ประโยคที่สมบูรณ์ทั้งประโยคแรก (1328 แถว) แต่ถึงแม้ว่ามันจะอยู่ในทรานแซคชัน (BEGIN), CONSTRAINT จะถูกตรวจสอบทันทีเมื่อจบแต่ละประโยคโดยไม่ทำ COMMIT ดังนั้นจึงสร้างข้อผิดพลาดเมื่อดำเนินการ INSERT ในที่สุดเราก็สร้าง CONSTRAINT DEFERRED ทำต่อไปนี้:
**Bloque 3**
ALTER TABLE public.ele_edivipol
DROP CONSTRAINT unique_div_nkit RESTRICT;
ALTER TABLE ele_edivipol
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY DEFERRED
หากเราดำเนินการแต่ละคำสั่งของ ** บล็อก 2 ** แต่ละประโยคแยกกันจะไม่มีการสร้างข้อผิดพลาดให้กับ INSERT เพราะมันไม่ได้ตรวจสอบ แต่คอมมิชชันขั้นสุดท้ายจะถูกดำเนินการเมื่อพบความไม่สอดคล้องกัน
สำหรับข้อมูลที่สมบูรณ์เป็นภาษาอังกฤษฉันขอแนะนำให้คุณตรวจสอบลิงก์:
ข้อ จำกัด SQL ที่เลื่อนออกไปในเชิงลึก
ไม่ผิดพลาดเมื่อเทียบกับ DEFERRABLE เริ่มต้นทันที