我有两张桌子 - 图书和 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,检查交易后的关系吗?
答案 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;