8

我希望 PostegreSQL 放松一点。每次我想更改视图中使用的列时,似乎我必须删除视图,更改字段然后重新创建视图。我可以放弃额外的保护,只告诉 PostgreSQL 让我更改字段,然后计算出对视图的调整吗?

澄清: 我明白什么是视图。事实上,这是因为视图就像一个子查询,我希望我可以只更改基础表并让视图获取更改。

假设我有以下内容:

CREATE TABLE monkey
(
  "name" character varying(50) NOT NULL,
)

CREATE OR REPLACE VIEW monkey_names AS 
 SELECT name
   FROM monkey

我真的只想在迁移脚本中执行以下操作,不必删除并重新创建视图。

ALTER TABLE monkey ALTER COLUMN "name" character varying(100) NOT NULL
4

1 回答 1

14

本案永久解决方案

要完全避免该问题,请使用数据类型textvarchar/character varying而不使用长度说明符,而不是character varying(n). 在手册中阅读这些数据类型。

CREATE TABLE monkey(name text NOT NULL)

如果您真的想强制执行最大长度,请创建一个CHECK约束

ALTER TABLE monkey 
  ADD CONSTRAINT monkey_name_len CHECK (length(name) < 101);

您可以随时更改或删除该约束,而无需触及视图等依赖对象,也无需由于类型更改而强制 Postgres 在表中写入新行(在现代版本的 Postgres 中不再需要)。

详细解释

正如@Michael 所提议的,我添加了一些更一般的信息:

PostgreSQL 中的视图不仅仅是“子查询的别名”。视图被实现为带有规则的特殊表ON SELECT TO my_view DO INSTEAD。(这就是您可以使用ALTER TABLE命令更改视图的原因。)您可以GRANT对其授予权限,添加注释甚至定义列默认值(对于规则很有用ON INSERT TO my_view DO INSTEAD...)。在此处此处阅读手册中的更多信息。

如果您更改底层对象,您也需要更改任何依赖视图的定义查询。该ALTER VIEW语句只能更改视图的辅助属性。用于CREATE OR REPLACE VIEW更改查询 - 它将保留任何其他属性。

但是,如果您想更改结果列的数据类型(如手头的情况),CREATE OR REPLACE VIEW这是不可能的。你必须对DROP旧的和CREATE新的看法。这永远不会删除基础表的任何数据。但是,它将删除视图的任何其他属性,这些属性也必须重新创建。

于 2011-12-15T22:56:17.530 回答