当您创建涉及许多表、外键约束、视图、触发器、函数等复杂数据库结构时,您隐式地创建对象之间的依赖项网络。例如,具有外键约束的表依赖于它引用的表。
确保整个数据库结构的完整性,PostgreSQL 保证您无法删除仍由其他对象依赖的对象。例如,尝试删除我们在第5.5.5节中考察的产品表(订单表依赖于它),将导致如下错误消息
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;
然后所有相关对象都将被删除,当然任何依赖于它们的对象也将递归删除。在本例中,它并未删除订单表,它仅仅删除了外键约束。它在此停止了,因为没有任何内容依赖于外键约束。(如果您想检查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;
则 DROP
将了解并强制执行函数对 my_colors
表的依赖性。