当您创建包含许多具有外键约束的表、视图、触发器、函数等的复杂数据库结构时,您会在对象之间隐式地创建一个依赖关系网络。例如,具有外键约束的表依赖于它引用的表。
为了确保整个数据库结构的完整性,PostgreSQL 确保您无法删除其他对象仍然依赖的对象。例如,尝试删除我们在 第 5.5.5 节 中考虑的 products 表,而 orders 表依赖于它,将导致类似于此的错误消息
DROP TABLE products; ERROR: cannot drop table products because other objects depend on it DETAIL: constraint orders_product_no_fkey on table orders depends on table products HINT: Use DROP ... CASCADE to drop the dependent objects too.
错误消息包含一个有用的提示:如果您不想费心单独删除所有依赖对象,您可以运行
DROP TABLE products CASCADE;
所有依赖对象将被删除,以及所有依赖于它们的任何对象(递归)。在这种情况下,它不会删除 orders 表,它只会删除外键约束。它到此为止,因为没有任何东西依赖于外键约束。(如果您想检查 DROP ... CASCADE
将做什么,请运行不带 CASCADE
的 DROP
并阅读 DETAIL
输出。)
几乎所有 PostgreSQL 中的 DROP
命令都支持指定 CASCADE
。当然,可能依赖关系的性质会随着对象类型的不同而不同。您还可以编写 RESTRICT
而不是 CASCADE
来获得默认行为,即阻止删除任何其他对象依赖的对象。
根据 SQL 标准,在 DROP
命令中需要指定 RESTRICT
或 CASCADE
。没有哪个数据库系统实际执行该规则,但默认行为是 RESTRICT
还是 CASCADE
则因系统而异。
如果 DROP
命令列出多个对象,则只有在指定组之外存在依赖关系时才需要 CASCADE
。例如,当说 DROP TABLE tab1, tab2
时,从 tab2
到 tab1
的外键的存在并不意味着需要 CASCADE
才能成功。
对于其主体定义为字符串文字的用户定义函数或过程,PostgreSQL 跟踪与函数的外部可见属性(如其参数和结果类型)相关的依赖关系,但不 跟踪只能通过检查函数主体才能知道的依赖关系。例如,考虑这种情况
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); CREATE TABLE my_colors (color rainbow, note text); CREATE FUNCTION get_color_note (rainbow) RETURNS text AS 'SELECT note FROM my_colors WHERE color = $1' LANGUAGE SQL;
(有关 SQL 语言函数的说明,请参见 第 36.5 节。) PostgreSQL 将意识到 get_color_note
函数依赖于 rainbow
类型:删除该类型将强制删除该函数,因为它的参数类型将不再定义。但是 PostgreSQL 不会认为 get_color_note
依赖于 my_colors
表,因此如果删除该表,它也不会删除该函数。虽然这种方法有缺点,但也有一些好处。如果该表丢失,该函数在某种意义上仍然有效,尽管执行它会导致错误;创建一个相同名称的新表将允许该函数再次工作。
另一方面,对于主体以 SQL 标准风格编写的 SQL 语言函数或过程,其主体在函数定义时解析,并且解析器识别的所有依赖关系都会被存储。因此,如果我们将上面的函数写成
CREATE FUNCTION get_color_note (rainbow) RETURNS text BEGIN ATOMIC SELECT note FROM my_colors WHERE color = $1; END;
那么函数对 my_colors
表的依赖关系将为人所知,并将由 DROP
强制执行。
如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符或需要进一步说明,请使用 此表格 报告文档问题。