2

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

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

视图的“值”在 where 条件下,所以Select *在这种情况下使用 a 是可以的。

当一个新列添加到基础表中时,我们必须重新定义视图

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

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

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

4

4 回答 4

4

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

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

exec sp_refreshview MyViewName
go

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

于 2012-10-31T15:43:15.350 回答
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
于 2010-01-14T10:50:54.927 回答
1

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

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

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

于 2010-01-14T14:48:59.243 回答
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 触发器做一些事情,但这会变得复杂。

于 2010-01-14T21:43:24.580 回答