我正在接受MySQL的挑战。如您所知,MySQL不会将NULL视为唯一索引中的重复值。
这里的问题是我有一个表但我需要强制执行以下列中没有类似的数据要插入“包括NULL” (call_code_id,result_code_id,action_method,action_id,assign_to,assign_to_type)
您可以建议我在这些列上添加唯一索引。 “assign_to”和“assign_id”列允许NULL值的问题。因此,基于MySQL对唯一列的定义,以下2组数据不是唯一的并且将被允许插入 (call_code_id,result_code_id,action_method,action_id,assign_to,assign_to_type) (1,1, '完成',NULL,5,2) (1,1, '完成',NULL,5,2)
所以即使我添加一个唯一的列,MySQL也会允许插入这两行。但我需要防止这种情况发生,因为我的应用程序认为这两行重复。
我必须在这里说我使用存储过程更新此表,并使用INSERT INTO ...... ON DUPLICATE KEY UPDATE语句更新表。
我的初步解决方案是在该表上添加2个触发器。第一个触发插入,另一个触发更新。如果在插入或更新之前找到类似的数据,则两个触发器都将返回错误代码1062。
这确实有效!但是新的挑战是INSERT INTO ...... ON DUPLICATE KEY UPDATE语句没有利用触发器返回的错误代码1062。但是,它在屏幕上返回1062错误,因此它正在找到应该的重复项。因此,当我执行INSERT INTO ...... ON DUPLICATE KEY UPDATE语句时,我得到屏幕上返回的错误1062,而不应该执行更新,因为我要求它在找到重复记录时更新。
以下是我的触发器语法
DROP TRIGGER IF EXISTS `return_1062_on_duplicate_on_insert`;
DELIMITER //
CREATE TRIGGER `return_1062_on_duplicate_on_insert` BEFORE INSERT ON `inventory_engine_test`
FOR EACH ROW BEGIN
IF EXISTS(SELECT 1 FROM inventory_engine_test
WHERE call_code_id = NEW.call_code_id
AND result_code_id = NEW.result_code_id
AND action_method = NEW.action_method
AND IFNULL(action_id, 0) = IFNULL(NEW.action_id, 0)
AND IFNULL(assign_to, 0) = IFNULL(NEW.assign_to, 0)
AND assign_to_type = NEW.assign_to_type
AND NEW.engine_id IS NOT NULL) THEN
SIGNAL SQLSTATE '23000'
SET MYSQL_ERRNO = 1062,
TABLE_NAME = 'inventory_engine_test',
MESSAGE_TEXT = 'Duplicate key found - return_1062_on_duplicate_on_insert trigger';
END IF;
END
//
DELIMITER ;
DROP TRIGGER IF EXISTS `return_1062_on_duplicate_on_update`;
DELIMITER //
CREATE TRIGGER `return_1062_on_duplicate_on_update` BEFORE UPDATE ON `inventory_engine_test`
FOR EACH ROW BEGIN
IF EXISTS(SELECT 1 FROM inventory_engine_test
WHERE call_code_id = NEW.call_code_id
AND result_code_id = NEW.result_code_id
AND action_method = NEW.action_method
AND IFNULL(action_id, 0) = IFNULL(NEW.action_id, 0)
AND IFNULL(assign_to, 0) = IFNULL(NEW.assign_to, 0)
AND assign_to_type = NEW.assign_to_type
AND NEW.engine_id IS NOT NULL) THEN
SIGNAL SQLSTATE '23000'
SET MYSQL_ERRNO = 1062,
TABLE_NAME = 'inventory_engine_test',
MESSAGE_TEXT = 'Duplicate key found - return_1062_on_duplicate_on_update trigger';
END IF;
END
//
DELIMITER ;
如何在INSPL INTO ..... ON DUPLICATE KEY UPDATE中考虑触发器的错误返回?
由于