Postgresql 重命名表而不更新视图定义

Pyr*_*ite 9 postgresql view postgresql-8.4

我今天发现在 Postgresql 中重命名表也会重命名使用我自动重命名的表的视图的 VIEW 定义?有什么办法可以关闭这个功能吗?

所以我重命名表:

ALTER TABLE xyz RENAME TO abc;
Run Code Online (Sandbox Code Playgroud)

举例来说,我的 VIEW 定义是:

CREATE VIEW foo AS SELECT * FROM xyz;
Run Code Online (Sandbox Code Playgroud)

重命名表后,我知道的下一件事是,foo 的定义已更改为指向表 abc。

我正在使用 Postgresql 8.4

--更新时间:2014 年 12 月 30 日下午 12:41--

这是一个测试用例来说明我的意思:

CREATE TABLE tmp_test_a (num integer);
CREATE VIEW v_tmp_test_a AS SELECT * FROM tmp_test_a;

-- Now look at what the VIEW is using (now is using tmp_test_a, which is what it should be using):
SELECT pg_get_viewdef('v_tmp_test_a'::regclass, false);

-- Now create a second table, and swap them.
CREATE TABLE tmp_test_b (num integer);
ALTER TABLE tmp_test_a RENAME TO tmp_test_c;
ALTER TABLE tmp_test_b RENAME TO tmp_test_a;
ALTER TABLE tmp_test_c RENAME TO tmp_test_b;

-- Now look at what the VIEW is using again (now is using tmp_test_b with an alias of tmp_test_a)
SELECT pg_get_viewdef('v_tmp_test_a'::regclass, false);

-- Cleanup
DROP VIEW v_tmp_test_a;
DROP TABLE tmp_test_a;
DROP TABLE tmp_test_b;
Run Code Online (Sandbox Code Playgroud)

小智 5

简单的答案 - 因为视图引用 OID 而不是对象名称。该名称在内部函数中被翻译回。

PostgreSQL 中的视图可以被认为是一个带有选择重写规则的空表。使用您的示例,重写规则的内部查询树位于pg_rewrite.ev_action表/列中,您将在那里看到对单个表和列 OID 的引用。

我建议做的是将表重命名和一个CREATE OR REPLACE VIEW语句包含在单个事务中,这样一切都会变得相对无缝,并且重新创建视图指向新表的 OID。