1

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 ;

問題は、(を使用してUPDATE .. SET Deleted = UTC_TIMESTAMP ..;) Customer テーブルからレコードを削除しようとすると、次のエラーが原因でクエリが失敗することです。

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(トリガーの continue ハンドラーで sqlstate を参照します)。何が間違っているのかわかりません。

MySQL の例外処理についてインターネットを検索しましたが、重要な答えが見つかりませんでした。誰かアイデアはありますか?

ご協力いただきありがとうございます!:-)

敬具、アーノルド・ピストリウス

4

2 に答える 2

0

アドレステーブルのcustomerid列がFOREIGNキーで顧客テーブルであり、customerid列が主キーであり、主キーにnull値がないため、CustomerId = nullを設定できません。

        UPDATE `Address` R
        SET
        R.CustomerId = NULL 
于 2013-08-27T10:19:08.777 に答える
0

PHP スクリプトを書き直すことにしました。参照されたフィールドが NULLABLE かどうかをチェックするようになりました。その場合、参照を NULL に設定します。それ以外の場合は、レコード全体を削除します。

于 2013-09-11T09:20:10.413 に答える