PostgreSQL:删除从另一个 table 引用的行
PostgreSQL: deleting rows referenced from another table
我有两个表,对象和 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 返回到对象的列不是一个选项。
是使用 CTE(通用 Table 表达式)
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
Sons 喜欢 ON UPDATE SET NULL
修饰符对您的 FK 约束的完美工作。 Per documentation:
SET NULL
Set the referencing column(s) to 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。
另外,这听起来很奇怪:
I have two tables, object and object_data, with object referencing
object_data by foreign key (the relation is 1:1)
通常,在这种情况下,我希望引用是从 object_data
到 object
的相反方向,但这只是猜测table 个名字。
您可以创建一个临时文件 table:
CREATE TEMP TABLE object_data_ids AS
SELECT object_data_id FROM object WHERE ...;
然后在更新和删除中使用临时 table:
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);
我有两个表,对象和 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 返回到对象的列不是一个选项。
是使用 CTE(通用 Table 表达式)
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
Sons 喜欢 ON UPDATE SET NULL
修饰符对您的 FK 约束的完美工作。 Per documentation:
SET NULL
Set the referencing column(s) to 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。
另外,这听起来很奇怪:
I have two tables, object and object_data, with object referencing object_data by foreign key (the relation is 1:1)
通常,在这种情况下,我希望引用是从 object_data
到 object
的相反方向,但这只是猜测table 个名字。
您可以创建一个临时文件 table:
CREATE TEMP TABLE object_data_ids AS
SELECT object_data_id FROM object WHERE ...;
然后在更新和删除中使用临时 table:
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);