mysql:更新表的主键,该主键被另一个表称为外键

时间:2020-04-02 03:05:54

标签: mysql

这是我的数据库结构

CREATE DATABASE Library;

CREATE TABLE Library.Book (
    ID        char(8),
    name      varchar(10) NOT NULL,
    author    varchar(10),
    price     float,
    status     int DEFAULT 0,
    PRIMARY KEY (ID),
    CHECK ( status >= 0 and status <= 1 ),
    CHECK ( price >= 0 )
);

CREATE TABLE Library.Reader (
    ID        char(8),
    name      varchar(10),
    age       int,
    address   varchar(20),
    PRIMARY KEY (ID)
);

CREATE TABLE Library.Borrow (
    Book_ID      char(8),
    Reader_ID    char(8),
    Borrow_Date  date,
    Return_Date  date,
    CONSTRAINT FK_Book_ID FOREIGN KEY (Book_ID) REFERENCES Library.Book(ID),
    CONSTRAINT FK_Reader_ID FOREIGN KEY (Reader_ID) REFERENCES Library.Reader(ID)
);

我写了一个如下的存储过程

DELIMITER //
CREATE PROCEDURE Library.ChangeBookID (IN OriginID char(8), IN ModifiedID char(8))
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION #处理异常
        SET @STATUS = 1;
    CREATE TABLE Library.book_copy
    SELECT ID
    FROM Library.Book;
    START TRANSACTION;
    UPDATE Library.book_copy
        SET Library.book_copy.ID = ModifiedID
        WHERE Library.book_copy.ID = OriginID;
    if @STATUS = 0 THEN   #status = 0 means no transaction
        ALTER TABLE Library.Borrow
        DROP FOREIGN KEY FK_Book_ID;

        UPDATE Library.Borrow
            SET Library.Borrow.Book_ID = ModifiedID
            WHERE Library.Borrow.Book_ID = OriginID;

        DROP TABLE Library.Book;
        RENAME TABLE Library.Book_copy TO Library.Book;

        ALTER TABLE Library.Borrow
        ADD CONSTRAINT FK_Book_ID FOREIGN KEY (Book_ID) REFERENCES Library.Book(ID);
        COMMIT;
    ELSE
        ROLLBACK ;
    END IF;
END //
DELIMITER ;

我想要的是,如果修改后的主键值与该表的其余部分冲突,则该过程将回滚,否则将提交更改。但是,它不符合我的预期。

1 个答案:

答案 0 :(得分:0)

我仍然不知道为什么我之前编写的存储过程出错了,但是在Barmar的帮助下,我找到了另一种更干净的方法来解决这个问题。 现在,新的存储过程如下:

DELIMITER //
CREATE PROCEDURE Library.ChangeBookID (IN OriginID char(8), IN ModifiedID char(8))
BEGIN
    START TRANSACTION;
    IF NOT EXISTS(SELECT 1 FROM Library.book WHERE ID = ModifiedID) THEN
        ALTER TABLE Library.Borrow
        DROP FOREIGN KEY FK_Book_ID;

        UPDATE Library.Book
            SET Library.Book.ID = ModifiedID
        WHERE Library.Book.ID = OriginID;

        UPDATE Library.Borrow
            SET Library.Borrow.Book_ID = ModifiedID
        WHERE Library.Borrow.Book_ID = OriginID;

        ALTER TABLE Library.Borrow
        ADD CONSTRAINT FK_Book_ID FOREIGN KEY (Book_ID) REFERENCES Library.Book(ID);

        COMMIT;
    ELSE
        ROLLBACK;
    END IF;
END //
DELIMITER ;

再次感谢Barmar,也感谢tad4的帮助。

相关问题