我在SQLite数据库中有表,它由外键引用,如树结构:
table1:
id
<other_fields>
table2:
id
table1_id (ON DELETE CASCADE)
<other_fileds>
table3:
id
table2_id (ON DELETE CASCADE)
<other_fields>
etc...
此数据来自服务器。 但是用户可以将自己的数据存储在数据库中(例如&#34;注释&#34;到任何记录)。 用户数据存储在附加表中,分别引用到Table1,Table2等
table1_user_data:
id
table1_id (ON DELETE RESTRICT) - to forbid deleting if user data exists
table2_user_data:
id
table2_id (ON DELETE RESTRICT)
如果我从根表(table1)中删除数据,我想保留属于&#34; branches&#34;的记录。对于用户数据,必须删除其他数据。
但是当我执行DELETE FROM table1
时 - 发生了外键约束并且没有(!)数据被删除。
但我想删除用户数据记录未引用的所有数据。
(例如,如果我只有一条评论(用户数据),引用table2中的一条记录,那么在删除之后我希望有这条评论,table2中的相应记录和table1中的一条记录(在哪条记录上)在表2中引用))
实施此策略的最佳方式是什么?
答案 0 :(得分:0)
当您告诉数据库删除某些记录时,某些记录实际上没有被删除(由于违反约束,或者从触发器引发错误或任何其他原因),那么整个DELETE语句被认为是失败了,并且流产了。
删除记录子集的唯一方法是向DELETE语句本身添加适当的过滤器:
DELETE FROM table1
WHERE id NOT IN (SELECT table1_id
FROM table1_user_data)
AND id NOT IN (SELECT table1_id
FROM table2
WHERE id IN (SELECT table2_id
FROM table2_user_data))
... etc.
或者,分别删除每条记录,以便您可以忽略约束违规错误,并且可以继续使用下一条记录:
SELECT id FROM table1;
-- for each returned id:
DELETE FROM table1 WHERE id = 123; -- ignore constraint errors
DELETE FROM table1 WHERE id = 456; -- ignore constraint errors
DELETE FROM table1 WHERE id = 789; -- ignore constraint errors
...