คีย์ที่ซ้ำกันไม่ทำอะไรเลย


14

ฉันกำลังแทรกลงในตารางต่อไปนี้โดยใช้ LuaSQL กับ PtokaX API

CREATE TABLE `requests` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `ctg` VARCHAR(15) NOT NULL,
    `msg` VARCHAR(250) NOT NULL,
    `nick` VARCHAR(32) NOT NULL,
    `filled` ENUM('Y','N') NOT NULL DEFAULT 'N',
    `dated` DATETIME NOT NULL,
    `filldate` DATETIME NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `nick_msg` (`nick`, `msg`),
    UNIQUE INDEX `ctg_msg` (`ctg`, `msg`)
)
COMMENT='Requests from users in any of the categories.'
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

ตอนนี้ปัญหาของฉันคือเมื่อผู้ใช้ (แสดงโดยnick) พยายามที่จะแทรกคำขอเดียวกันอีกครั้งUNIQUEดัชนีมีการตรวจสอบและสคริปต์กลับเท็จ นี่ทำให้สคริปต์ของฉันล้มเหลวและฉันต้องรีสตาร์ทสคริปต์

มีบางอย่างที่ฉันสามารถทำได้ในINSERT ... ON DUPLICATE KEYคำสั่งเพื่อที่จะไม่ทำอะไรเลยหรืออย่างน้อยก็ไม่กลับข้อผิดพลาดในกรณีที่DUPLICATE KEY?

ไม่เช่นนั้นฉันต้องไปอัปเดตdatedฟิลด์ของฉันด้วยDATETIMEค่าใหม่

คำตอบ:


23

สามวิธี ทั้งIGNOREข้อผิดพลาดที่ซ้ำกัน:

INSERT IGNORE 
  ... ;                   -- without ON DUPLICATE KEY

หรือพยายามอัพเดตซ้ำซ้อนเมื่อมีสิ่งที่ซ้ำกัน:

INSERT 
  ... 
ON DUPLICATE KEY UPDATE
  id = id ;

หรือตรวจสอบรายการที่ซ้ำกันก่อนใส่:

INSERT INTO requests
  (id, ctg, msg, nick, filled, dated, filldate)
SELECT
  NULL, 'urgent', 'Help!', 'Hermione', 'Y', NOW(), NOW()
FROM
  dual
WHERE NOT EXISTS
      ( SELECT *  FROM requests  WHERE (nick, msg) = ('Hermione', 'Help!') )
  AND NOT EXISTS
      ( SELECT *  FROM requests  WHERE (ctg, msg) = ('urgent', 'Help!') ) ;

ความแตกต่างระหว่างวิธีที่ 3 และสองคนแรกคือเมื่อมีการทำซ้ำidจะไม่เพิ่มขึ้น ด้วยINSERT IGNOREและINSERT ... ON DUPLICATE KEYจะเพิ่มอัตโนมัติและเนื่องจากการแทรกจะไม่ทำคุณจะมีช่องว่างในค่าของidก็จะเป็นรถยนต์ที่เพิ่มขึ้นและตั้งแต่แทรกจะไม่สามารถทำได้คุณจะมีช่องว่างในค่าของ

ฉันควรเพิ่มว่าสคริปต์ของคุณควรตรวจสอบข้อผิดพลาดอยู่เสมอและไม่ล้มเหลวเมื่อมี แบบสอบถามหรือคำสั่งใด ๆ สามารถล้มเหลวและกลับข้อผิดพลาดเป็นครั้งคราวด้วยเหตุผลต่างๆ เทคนิคข้างต้นจะช่วยให้คุณประหยัดจากข้อผิดพลาดประเภทใดประเภทหนึ่งเท่านั้น


1

ตัวเลือกที่ยอดเยี่ยมฉันเพิ่งรู้หนึ่งในสี่ คุณสามารถสร้างขั้นตอนดังต่อไปนี้ (MySQL 5.5 หรือสูงกว่า)

DELIMITER ;;
CREATE PRODECURE...
...necessary parameters...
BEGIN

DECLARE v_dups BIGINT;
DECLARE CONTINUE HANDLER FOR 1062 SET v_dups = v_dups + 1;

-- RUN SIMPLE INSERT, IF IT TAKES DUPLICATE KEY NOTHING HAPPENS
END;;

ดีฉันไม่ได้ใช้ MySQL เมื่อเร็ว ๆ นี้ดังนั้นฉันไม่รู้ คุณสามารถอัปเดตและทำอย่างละเอียดใน: เกิดอะไรขึ้นถ้ามีข้อผิดพลาดอื่น ๆ (ไม่ใช่การละเมิดคีย์ที่ซ้ำกัน) เกิดขึ้น? และสิ่งนี้ทำงานอย่างไร (1,062 หมายถึงอะไร) แบบสอบถามต้องมีการแทรกคำเดี่ยวหรือสามารถใช้แทรกหลายแถวได้หรือไม่
ypercubeᵀᴹ

1,062 คือแถวซ้ำ ข้อผิดพลาด SQL นี้เท่านั้นที่ทริกเกอร์: SET v_dups = v_dups + 1;
billmask
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.