2010-01-14 47 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 *的其他意見一致。

相關問題