This is my DB structure
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)
);
and I write a store procedure as below
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 ;
What I want is that if the modified primary key value is conflicted with the rest of this table, the procedure will rollback, else it will commit the changes. However, it doesn't work as I expected.
I still do not know why the store procedure I wrote before goes wrong, but with Barmar's help, I get another way which is much cleaner to solve this question. Now, the new store procedure is as below:
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 ;
Thank Barmar again and also thx4 tadman's help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.