首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在MySQL (引用完整性)中执行异常处理

如何在MySQL (引用完整性)中执行异常处理
EN

Stack Overflow用户
提问于 2013-08-27 09:16:28
回答 2查看 393关注 0票数 1

MySQL version: 5.6.12

大家好,

我有一个MySQL数据库,其中包含几个表和外键。由于恢复的目的,我需要通过在表的“删除”字段中填充删除时间戳来对记录进行软删除(null表示它没有被删除)。现在,我想要创建一个触发器,如果已删除的项目的父项被删除,则该触发器将取消已删除项的链接。为了澄清,我做了一个小演示脚本:

表arnold_test.Customer:

代码语言:javascript
复制
CREATE SCHEMA IF NOT EXISTS `arnold_test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `arnold_test` ;

-- -----------------------------------------------------
-- Table `arnold_test`.`Customer`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `arnold_test`.`Customer` (
  `CustomerId` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `Name` VARCHAR(45) NULL,
  `Email` VARCHAR(45) NULL,
  `Phone` VARCHAR(45) NULL,
  `Deleted` DATETIME NULL,
  PRIMARY KEY (`CustomerId`))
ENGINE = InnoDB;

表arnold_test.Address

代码语言:javascript
复制
-- -----------------------------------------------------
-- Table `arnold_test`.`Address`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `arnold_test`.`Address` (
  `AddressId` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `CustomerId` INT UNSIGNED NOT NULL,
  `Street` VARCHAR(45) NULL,
  `ZipCode` VARCHAR(45) NULL,
  `State` VARCHAR(45) NULL,
  `City` VARCHAR(45) NULL,
  `Country` VARCHAR(45) NULL,
  `Deleted` DATETIME NULL,
  PRIMARY KEY (`AddressId`),
  INDEX `fk_Address_Customer_idx` (`CustomerId` ASC),
  CONSTRAINT `fk_Address_Customer`
    FOREIGN KEY (`CustomerId`)
    REFERENCES `arnold_test`.`Customer` (`CustomerId`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

删除触发器:

代码语言:javascript
复制
USE `arnold_test`;

DELIMITER $$
USE `arnold_test`$$
CREATE
DEFINER=`root`@`%`
TRIGGER `arnold_test`.`NinjaDeleteTrigger_Customer`
BEFORE UPDATE ON `arnold_test`.`Customer`
FOR EACH ROW
BEGIN

    IF OLD.Deleted IS NULL AND NEW.Deleted IS NOT NULL THEN


        BEGIN


            DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' BEGIN
                UPDATE `arnold_test`.`Address` R
                SET    R.Deleted = NEW.Deleted
                WHERE
                    OLD.CustomerId = R.CustomerId            
                    AND R.Deleted IS NULL;
            END;

            UPDATE `arnold_test`.`Address` R
            SET
                R.CustomerId = NULL        
            WHERE
                NEW.CustomerId = R.CustomerId        
                AND R.Deleted IS NULL;


        END;



    END IF;

END$$


DELIMITER ;

现在的问题是,当我尝试从Customer表中删除记录时(通过使用UPDATE .. SET Deleted = UTC_TIMESTAMP ..;),查询会因为以下错误而失败:

代码语言:javascript
复制
ERROR 1452: 1452: Cannot add or update a child row: a foreign key constraint fails (`arnold_test`.`Address`, CONSTRAINT `fk_Address_Customer` FOREIGN KEY (`CustomerId`) REFERENCES `Customer` (`CustomerId`) ON DELETE NO ACTION ON UPDATE NO ACTION)

当我使用GET DIAGNOSTICS CONDITION 1 @p1 = RETURNED_SQLSTATE; SELECT @p1;检索SQLSTATE代码时,响应是23000 (该响应引用触发器中继续处理程序中的sqlstate )。我不知道我做错了什么。

我在MySQL上搜索异常处理,但找不到关键答案。有人有什么想法吗?

谢谢你的帮助!-)

你好,阿诺德·皮斯托瑞斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-11 09:20:10

我选择重写我的PHP脚本。现在,它检查所引用的字段是否为NULLABLE。如果是这样,则将引用设置为NULL,否则将删除整个记录。

票数 0
EN

Stack Overflow用户

发布于 2013-08-27 10:19:08

您不能设置CustomerId = null,因为在address表中有customerid列是外键和customer表,customerid列是主键,主键没有空值。

代码语言:javascript
复制
        UPDATE `Address` R
        SET
        R.CustomerId = NULL 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18461500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档