在事务之后删除关系中的记录

时间:2014-06-02 13:03:00

标签: mysql

我有两张桌子 - 图书 books_authors ,其中包含 books_authors.user_id books.id <之间的关系/ em>带有标志的列 ON DELETE CASCADE

我还有从XML文件导入数据到DB的机制,问题是,当我想用​​新数据重新加载整个 books 表时, books_authors中的所有记录消失,甚至关系实际上都存在。这种机制的MySQL代码如下:

START TRANSACTION;
DELETE * FROM books;
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
...
COMMIT;

此次交易后,我的图书表中包含新数据,但 books_authors 表格为空。

我可以做任何事情告诉MySQL,检查交易后的关系吗?

2 个答案:

答案 0 :(得分:2)

如果您不希望books表上的删除级联到books_authors,则需要暂时​​禁用FOREIGN_KEY_CHECKS会话变量。

然后,如果要在重新插入books表后删除孤立记录,可以使用多表删除语法和外连接来执行此操作。

这样的事情应该有效:

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;

DELETE * FROM books;
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
...

delete      c.*
from        books_authors c
left join   books p
on          c.book_id=p.id
where       p.id is null;

SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;

答案 1 :(得分:0)

一种可能的解决方案是将所有记录从books_authors复制到临时表,删除所有书籍,插入更新的书籍,然后通过books_authors_tmp和书籍之间的连接恢复books_authors记录(因此只有现有书籍关系将是恢复)。像这样:

START TRANSACTION;

DROP TEMPORARY TABLE IF EXISTS books_authors_tmp;
CREATE TEMPORARY TABLE IF NOT EXISTS books_authors_tmp 
AS (SELECT * FROM books_authors);

DELETE * FROM books;
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
INSERT books (...) VALUES (...);
...

INSERT INTO books_authors
SELECT bat.*
FROM books b
INNER JOIN books_authors_tmp bat
ON
    b.id = bat.bookId;

DROP TEMPORARY TABLE IF EXISTS books_authors_tmp;

COMMIT;