我有两个表,object和object_data,对象通过外键引用object_data(关系是1:1)。对于一组对象,我需要将其object_data引用置空并删除相应的object_data行,如下所示:
DELETE FROM object_data WHERE id IN
( SELECT object_data_id FROM object WHERE ... );
UPDATE object SET object_data_id = NULL WHERE ...;
问题是,外键约束不允许删除仍然从对象引用的object_data行。
我当前的解决方案是将SELECT
的结果读入列表,然后将外键置零,然后使用IN运算符以合理大小的批量删除object_data行。有更好的解决方案吗?添加从object_data引用回对象的列不是一个选项。
答案 0 :(得分:6)
对于你的FK约束的ON UPDATE SET NULL
修饰符来说,这是一个完美的工作。 Per documentation:
SET NULL
将引用列设置为null。
ALTER TABLE object DROP CONSTRAINT <fk_name_here>;
ALTER TABLE object ADD CONSTRAINT <fk_name_here>
FOREIGN KEY ON (object_data_id) REFERENCES object_data (object_data_id)
ON DELETE SET NULL;
猜测PK名称也是object_data_id
。那么你所需要的只是:
DELETE FROM object_data WHERE id ...
object
中的敬意者自动设为NULL。
除此之外,这听起来很奇怪:
我有两个表,object和object_data,带有对象引用 object_data by foreign key(关系是1:1)
通常情况下,在这种情况下,我希望引用是object_data
到 object
的另一种方式,但这只是猜测来自表名。
答案 1 :(得分:4)
是使用CTE(通用表格表达式)
WITH tmp AS (SELECT object_data_id FROM object WHERE ...),
upd AS (UPDATE object SET object_data_id = NULL WHERE ...)
DELETE FROM object_data
WHERE id IN (SELECT object_data_id FROM tmp);
首先执行第一个名为tmp的CTE,并记住以后需要的数据 名为upd的第二个CTE会将字段设置为NULL 最后,DELETE使用来自tmp的数据来执行DELETE
答案 2 :(得分:0)
您可以创建临时表:
CREATE TEMP TABLE object_data_ids AS
SELECT object_data_id FROM object WHERE ...;
然后在更新和删除中使用临时表:
UPDATE object SET object_data_id = NULL WHERE object_data_id IN
(SELECT object_data_id FROM object_data_ids);
DELETE FROM object_data WHERE id IN
(SELECT object_data_id FROM object_data_ids);