当你创建复杂的数据库结构,其中涉及许多带有外键约束的表、视图、触发器、函数等时,你实际上是在对象之间创建了一个依赖关系网络。例如,带有外键约束的表依赖于它引用的表。
为了确保整个数据库结构的完整性,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
强制执行。
如果您发现文档中有任何不正确、与您特定功能的使用体验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。