如何在基础表更改时自动重新定义视图(新列)?

时间:2010-01-14 10:41:26

标签: sql oracle views ddl

我们有一个像这样定义的视图

CREATE VIEW aView as 
SELECT * from aTable Where <bunch of conditions>;

视图的“值”在where-condition中,因此在这种情况下可以使用Select *

当新列添加到基础表时,我们必须使用

重新定义视图
CREATE OR REPLACE FORCE VIEW aView as 
SELECT * from aTable Where <bunch of conditions>;

因为Select *似乎被“翻译”到视图(重新)定义时出现的所有列。

我的问题:我们怎样才能避免这一额外的步骤? (如果答案取决于RDBMS,我们使用的是Oracle。)

4 个答案:

答案 0 :(得分:4)

我知道您指定了Oracle,但SQL Server中的行为是相同的。

使用新列更新视图的一种方法是使用:

exec sp_refreshview MyViewName
go

当然,我也同意其他关于在视图定义中不使用SELECT *的评论。

答案 1 :(得分:3)

Oracle中必须执行此额外步骤:您必须手动重新编译视图。

正如您所注意到的,创建视图后会丢失“*”:

SQL> create table t (id number);

Table created

SQL> create view v as select * from t;

View created

SQL> select text from user_views where view_name = 'V';

TEXT
-------------------------------------------------------
select "ID" from t

答案 2 :(得分:1)

您不应在视图中使用*明确指定列。

通过这种方式,您只需检索所需的数据,从而避免潜在的问题,即有人向您不希望该视图返回的表添加列(例如,会产生负面影响的大型二进制列性能)。

是的,您需要重新编译视图以添加另一列,但这是正确的过程。这样就可以避免其他编译问题,例如,如果视图引用了两个表,并且有人在其中一个表中添加了重复的列名。如果您没有使用表别名为该列的引用添加前缀,则编译器将确定引用哪些列的问题,或者如果结果中存在重复的列名称,则可能会抱怨。

答案 3 :(得分:0)

扩展模型时会自动更新视图以添加列,例如

SELECT a.*, std_name_format(a.first_name, a.middle_names, a.last_name) long_name

甚至

SELECT a.*, b.* from table_a a join table_b b....

如果您只有 SELECT * FROM table 的视图,那么您可能应该使用同义词或直接寻址表。

如果视图隐藏行( SELECT * FROM table WHERE ... ),那么您可以查看各种称为细粒度访问控制(FGAC),行级安全性(RLS)的功能)或虚拟专用数据库(VPD)。

您可以使用DDL触发器执行某些操作,但这会变得复杂。