2010-01-14 50 views
1

我们已经找到的已定义的观点一样,这如何在基础表更改时自动重新定义视图(新列)?

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

的“价值”在哪里,状态的图,所以它是好的,在这种情况下,使用Select *

当一个新列被添加到基础表,我们必须重新定义了

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

视图为Select *似乎变得“翻译”成所有出席的观点是时间列(重新)定义。

我的问题:我们如何避免这个额外的步骤? (如果答案依赖于RDBMS,我们使用的是Oracle。)

回答

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 
+0

其他数据库呢? – Thorsten 2010-01-14 15:58:29

1

你不应该用你的意见*显式指定列。

这样你就只需要检索你需要的数据,从而避免了有人在某个表中添加一列而不希望该视图返回的潜在问题(例如,一个大的二进制列对性能产生不利影响)。

是的,你需要重新编译视图来添加另一列,但这是正确的过程。这样可以避免其他编译问题,例如视图引用两个表,并且有人在其中一个表中添加重复的列名。如果您没有使用表别名前缀对列的引用,那么编译器会在确定引用哪列时遇到问题,或者如果结果中有重复的列名,可能会投诉。

+1

我不完全同意你的看法。 a。如上所述,我认为在这种情况下Select *是可以接受的。 b。我认为RDBMS处理编译问题非常适用于也依赖于表结构并使不正确的实体失效的程序触发器等。此外,如果删除基础表中的必需列,则视图会失效,为什么不能以其他方式处理事情? – Thorsten 2010-01-14 15:56:09

0

与自动更新视图如果您只有SELECT *从视图中添加列来当你扩展你的模型,例如

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.... 

问题表,那么你可能应该使用同义词或直接寻址表。那么您可以查看不同地称为细粒度访问控制(FGAC),行级安全性(RLS)或虚拟专用服务器(Virtual Private)的功能部件数据库(VPD)。

你可能可以用DDL触发器做些事情,但这会变得复杂。

+0

也许需要更多的背景:我想从基表中定义一个包含所有“活动”记录的视图。 Where-Clause由5个不同的条件组成,其中有一些像'aCol Not in(<8 values>)等不便使用的东西。使用视图只是方便的(并且一致)。这不是'安全'。 – Thorsten 2010-01-14 22:07:33

4

我知道你指定的是Oracle,但在SQL Server中的行为是一样的。更新与新列视图

一种方法是使用:

exec sp_refreshview MyViewName 
go 

当然,我也有关于在视图定义中不使用SELECT *的其他意见一致。

相关问题