SQL复合键关联表批量插入匹配数据及外键删除影响咨询
批量插入关联行解决方案
你可以直接通过CROSS JOIN(交叉连接)匹配符合条件的Foo记录和Fruits记录,单次SQL即可完成批量插入,不需要应用层循环,性能远高于逐行插入。
示例SQL如下,假设你要给Foo表中Chr1 = 'a'且Chr2 = 'b'的记录,关联所有Name满足%nberry规则的Fruits:
INSERT INTO FooFruits ([Chr1], [Chr2], [Type], [Name]) SELECT f.[Chr1], f.[Chr2], fr.[Type], fr.[Name] FROM Foo f CROSS JOIN Fruits fr WHERE f.[Chr1] = 'a' AND f.[Chr2] = 'b' -- 这里替换为你要匹配的Foo过滤条件 AND fr.[Name] LIKE '%nberry' -- 可选:添加下面的条件避免插入重复关联导致主键冲突 AND NOT EXISTS ( SELECT 1 FROM FooFruits ff WHERE ff.[Chr1] = f.[Chr1] AND ff.[Chr2] = f.[Chr2] AND ff.[Type] = fr.[Type] AND ff.[Name] = fr.[Name] )
这个方案直接在数据库层面完成所有匹配和插入,即使后续Foo和Fruits表达到你预估的最大规模,执行效率也完全足够。
删除主表行时关联表的行为
这个结果取决于你是否给FooFruits表设置了外键约束:
- 如果没有设置外键约束:删除Foo或Fruits中的行时,FooFruits里对应的关联记录不会有任何变化,会变成没有对应主表数据的孤立脏数据。
- 如果设置了外键约束,行为由你指定的约束规则决定:
RESTRICT/NO ACTION:只要FooFruits里还有对应的关联记录,就不允许你删除Foo/Fruits中的对应行,会直接报错提示存在关联。CASCADE(级联删除):删除Foo/Fruits中的行时,FooFruits里所有对应的关联记录会被自动同步删除。SET NULL/SET DEFAULT:由于FooFruits的四个字段都是复合主键的组成部分,不允许为NULL,这个规则不适用于你的场景。
如果后续用PyQt5的QSqlTableModel操作数据,建议要么在数据库层面直接设置外键级联删除,要么在应用层删除主表记录前,先手动删除对应的FooFruits关联行,避免产生脏数据。
内容的提问来源于stack exchange,提问作者UnsweetIceTea
相关产品推荐
相关产品推荐

