这是我的数据库结构
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 ;
我想要的是,如果修改后的主键值与该表的其余部分冲突,则该过程将回滚,否则将提交更改。但是,它不符合我的预期。
答案 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的帮助。