例如,假设DB具有外键A.b_id->删除时SET为NULL的B.id。如果删除了具有某些B.id的记录,则所有B_id引用都将设置为NULL。
但是,如果A已经包含A.b_id的值不在b.id中的记录(它是在不支持外键的情况下插入的(,是否有办法强制SQLite DB检查外键并将此类数据设置为NULL?
事实上,首先我要解决一个数据库升级任务。
启动应用程序时,检查内部数据库(资源(的版本是否高于用户数据库。如果是这样,它会备份用户数据库,并将内部空数据库复制到用户存储中。Than关闭了外键支持,并用备份中的数据填充新的数据库,为所有具有相同名称的列逐表自动插入循环中。打开外键支持返回。
一切都很好,但如果在旧数据库的某个表中以前没有外键约束,而新数据库有外键约束,则数据将按原样插入,链接无法指向任何地方(可能错误的链接是不可避免的,与问题无关(。
是的,我知道一种在不关闭外键支持的情况下插入的方法,但它需要了解我希望避免的表依赖顺序。
感谢您提前提供的帮助!
虽然我不知道有什么方法可以自动将表中一列的所有孤立值设置为NULL
,但有一种方法可以获得所有这些情况的报告,然后采取相应的行动
这是PRAGMA
语句foreign_key_check
:
PRAGMA schema.foreign_key_check;
或单表检查:
PRAGMA schema.foreign_key_check(table-name);
来自文档:
foreign_key_check杂注检查数据库或调用的表"表名";,针对违反的外键约束。这个foreign_key_check杂注为每个外键返回一行输出违反每个结果行中有四列。第一列是包含REFERENCES子句的表的名称。这个第二列是包含无效的行的rowidREFERENCES子句,如果子表是WITH ROWID,则为NULL桌子第三列是所引用的表的名称。第四列是特定外键约束的索引失败了。foreign_key_check输出中的第四列pragma与foreign_key_list杂注。当一个";表名";是指定的检查的外键约束是由REFERENCES创建的约束CREATE TABLE语句中的子句。
查看使用此PRAGMA
语句或其对应函数pragma_foreign_key_check()
的简化演示
您可以获得每个表中所有有问题行的rowid
的列表
在您的情况下,您可以执行一个UPDATE
语句,该语句将所有孤立的b_id
都设置为NULL
:
UPDATE A
SET b_id = NULL
WHERE rowid IN (SELECT rowid FROM pragma_foreign_key_check() WHERE "table" = 'A')
这也适用于SQLite:的后续版本
UPDATE A
SET b_id = NULL
WHERE rowid IN (SELECT rowid FROM pragma_foreign_key_check('A'))
但它似乎不适用于SQLite 3.27.0