3

如何查看哪些条目依赖于使用 PostgreSQL 的给定条目?(从属的意思是“有一个引用条目的外键”)。

基本上,我想检查当我DELETE给定表格条目时哪些条目可能被级联。

4

3 回答 3

3

要通过 fk 约束查看所有实际行,请使用下面描述的工具识别列。

在用 定义外键约束的地方ON DELETE CASCADE,依赖行将被删除(可能级联DELETE到更多依赖表)。

ON DELETE SET NULL在使用/定义外键约束的情况下ON DELETE SET DEFAULT,只有列中的值将重置为NULL/ 默认值。

否则DELETE,具有依赖行的行将失败并出现异常。

然后在已识别的表/列上运行如下查询:

SELECT f.tbl_fk_id, f.col_fk
FROM   tbl_fk f
JOIN   tbl t ON f.col_fk = t.col
AND    <same condition as DELETE here>;

pgAdmin提供了这个特性:

家属

在左侧的对象浏览器中选择对象,然后选择右上角的依赖项窗格。

pgAdmin 使用对系统目录的几个查询来组装列表。如果您想自己构建查询,您可以记录发出的命令。

此外,在删除您对依赖项不完全确定的对象时,请先尝试简单的DROP(不带CASCADE)。如果存在任何依赖项,您将收到一条错误消息...

最后,但要谨慎行事!,您可以启动事务并发出以下命令:

BEGIN;
DROP TABLE tbl CASCADE;

然后,如果你喜欢你所看到的:

COMMIT;

如果您不这样做:

ROLLBACK;

就像它从未发生过一样。;)

你会看到这样的东西:

NOTICE:  drop cascades to 4 other objects
DETAIL:  drop cascades to constraint tbl1_tbl_id_fkey on table myschema.tbl1
drop cascades to constraint tbl_winner_tbl_id_fkey on table myschema.tbl_foo
drop cascades to constraint bar_tbl_id_fkey on table myschema.bar
drop cascades to constraint tbl1_tbl_id_fkey on table x.tbl1

Query returned successfully with no result in 47 ms.
于 2012-10-05T15:29:19.913 回答
2

您可以直接从 PostgreSQL 系统目录中查询:

SELECT
  depending.relname as depending_table,
  referenced.relname as referenced_table
FROM pg_catalog.pg_depend d
JOIN pg_catalog.pg_constraint fkey ON fkey.oid=d.objid AND fkey.contype='f'
JOIN pg_catalog.pg_class depending ON depending.oid=fkey.conrelid
JOIN pg_catalog.pg_class referenced ON referenced.oid=d.refobjid
WHERE fkey.confdeltype='c'             -- just cascading deletes
  AND referenced.oid != depending.oid  -- ignoring reflexive dependencies
  AND referenced.relkind='r'           -- tables only

请参阅此 SQL Fiddle和相关文档:

扩展它以告诉您所涉及的列作为练习留给读者。(提示:pg_attribute。)

于 2012-10-05T15:56:31.813 回答
2

现有答案使用pg_catalog,这是可以的,但可以在 PostgreSQL 的主要版本之间不兼容地更改。只要有可能,您应该使用information_schema

SELECT *
FROM  information_schema.constraint_column_usage ccu
INNER JOIN information_schema.referential_constraints rc 
USING (constraint_catalog, constraint_schema, constraint_name);

看:

于 2012-10-06T01:46:36.933 回答