นี่คือขั้นตอนการจัดเก็บ (ภาษาถิ่น MySQL):
DELIMITER $$
DROP PROCEDURE IF EXISTS SetDefaultForZip;
CREATE PROCEDURE SetDefaultForZip (NEWID INT)
BEGIN
DECLARE FOUND_TRUE,OLDID INT;
SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
IF FOUND_TRUE = 1 THEN
SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
IF NEWID <> OLDID THEN
UPDATE PostalCode SET isDefault = FALSE WHERE ID = OLDID;
UPDATE PostalCode SET isDefault = TRUE WHERE ID = NEWID;
END IF;
ELSE
UPDATE PostalCode SET isDefault = TRUE WHERE ID = NEWID;
END IF;
END;
$$
DELIMITER ;
เพื่อให้แน่ใจว่าตารางของคุณสะอาดและขั้นตอนการจัดเก็บทำงานอยู่สมมติว่า ID 200 เป็นค่าเริ่มต้นให้รันขั้นตอนเหล่านี้:
ALTER TABLE PostalCode DROP INDEX isDefault_ndx;
UPDATE PostalCodes SET isDefault = FALSE;
ALTER TABLE PostalCode ADD INDEX isDefault_ndx (isDefault);
CALL SetDefaultForZip(200);
SELECT ID FROM PostalCodes WHERE isDefault = TRUE;
แทนที่จะเป็นขั้นตอนการจัดเก็บทริกเกอร์ล่ะ?
DELIMITER $$
CREATE TRIGGER postalcodes_bu BEFORE UPDATE ON PostalCodes FOR EACH ROW
BEGIN
DECLARE FOUND_TRUE,OLDID INT;
IF NEW.isDefault = TRUE THEN
SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
IF FOUND_TRUE = 1 THEN
SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
UPDATE PostalCodes SET isDefault = FALSE WHERE ID = OLDID;
END IF;
END IF;
END;
$$
DELIMITER ;
เพื่อให้แน่ใจว่าตารางของคุณสะอาดและทริกเกอร์ทำงานอยู่สมมติว่า ID 200 เป็นค่าเริ่มต้นให้รันขั้นตอนเหล่านี้:
DROP TRIGGER postalcodes_bu;
ALTER TABLE PostalCode DROP INDEX isDefault_ndx;
UPDATE PostalCodes SET isDefault = FALSE;
ALTER TABLE PostalCode ADD INDEX isDefault_ndx (isDefault);
DELIMITER $$
CREATE TRIGGER postalcodes_bu BEFORE UPDATE ON PostalCodes FOR EACH ROW
BEGIN
DECLARE FOUND_TRUE,OLDID INT;
IF NEW.isDefault = TRUE THEN
SELECT COUNT(1) INTO FOUND_TRUE FROM PostalCode WHERE isDefault = TRUE;
IF FOUND_TRUE = 1 THEN
SELECT ID INTO OLDID FROM PostalCode WHERE isDefault = TRUE;
UPDATE PostalCodes SET isDefault = FALSE WHERE ID = OLDID;
END IF;
END IF;
END;
$$
DELIMITER ;
UPDATE PostalCodes SET isDefault = TRUE WHERE ID = 200;
SELECT ID FROM PostalCodes WHERE isDefault = TRUE;
PostalCodes
จะว่างเปล่าเมื่อไหร่? หากแถวมีคุณสมบัติควรมีการป้องกันไม่ให้ถูกตั้งค่าเป็นเท็จเว้นแต่มีการตั้งค่าแถวอื่น (ถ้ามี) เป็นจริงภายในคำสั่ง SQL เดียวกันหรือไม่ แถวศูนย์จะมีคุณสมบัติระหว่างขอบเขตของธุรกรรมหรือไม่ แถวสุดท้ายในตารางควรถูกบังคับให้มีคุณสมบัติและป้องกันไม่ให้ถูกลบหรือไม่ ประสบการณ์บอกฉันว่า "รับประกันหนึ่งแถวอย่างแน่นอน" มีแนวโน้มที่จะหมายถึงบางสิ่งที่แตกต่างในความเป็นจริงมักจะ "ไม่เกินหนึ่งแถว"