mysql: обновить первичный ключ таблицы, который другой таблицей называется внешним ключом - PullRequest
0 голосов
/ 02 апреля 2020

Это моя структура БД

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 голосов
/ 02 апреля 2020

Я до сих пор не знаю, почему процедура хранения, которую я написал ранее, идет не так, но с помощью Бармара я получаю другой способ, который намного чище, чтобы решить этот вопрос. Теперь процедура нового магазина выглядит следующим образом:

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, а также помощь thx4 tadman.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...