簡體   English   中英

如何在MySQL中執行異常處理(參照完整性)

[英]How can I perform exception handling in MySQL (referential integrity)

MySQL version: 5.6.12

大家好,

我有一個MySQL數據庫,該數據庫下有幾個表和外鍵。 由於出於修訂目的,我需要通過在表的Deleted字段中填充刪除的時間戳來對記錄進行軟刪除(null表示不會刪除)。 現在,我想創建一個觸發器,如果​​已刪除其父項,則取消鏈接已刪除項。 為了澄清,我做了一個小的演示腳本:

表arnold_test.Customer:

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

-- -----------------------------------------------------
-- 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;

刪除觸發器:

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 ..; )時,由於以下錯誤,查詢失敗:

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代碼時, GET DIAGNOSTICS CONDITION 1 @p1 = RETURNED_SQLSTATE; SELECT @p1; GET DIAGNOSTICS CONDITION 1 @p1 = RETURNED_SQLSTATE; SELECT @p1; 響應為23000 (它在觸發器的繼續處理程序中引用了sqlstate)。 我不知道自己在做什么錯。

我在Internet上搜索了MySQL中的異常處理,但找不到關鍵的答案。 有人有想法嗎?

謝謝你的幫助! :-)

親切的問候,阿諾·皮斯托里烏斯

您不能將CustomerId設置為null,因為地址表中的customerid列是FOREIGN鍵和customer表,customerid列是主鍵,而主鍵沒有null值。

        UPDATE `Address` R
        SET
        R.CustomerId = NULL 

我選擇重寫我的PHP腳本。 現在,它檢查引用的字段是否為NULLABLE。 如果是這樣,它將引用設置為NULL,否則它將刪除整個記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM