oracle視圖

問題:什麼是視圖?
回答:
視圖也是一種數據庫對象,英文叫做“view”。視圖的本義就是與客戶交互的窗口。

簡單理解有點象一個容器,窗口中只能存放一條查詢語句。當“select * from 視圖名“,其實執行的是容器中的查詢語句。所以查詢視圖也可以得到數據,不過這些數據都是經過查詢語句“加工”以後的數據,可能與原表的記錄完全不同。

顯然:通過視圖所看到的數據,就象是看到化過妝以後的女人。兩者可能相差很大。

問題:使用視圖有什麼好處?
回答:
1、數據訪問控制。注意視圖也是一個數據庫對象。如果限制用戶只能通過視圖訪問數據,那麼就可能限制用戶訪問指定的數據,而不是數據庫中的原始數據。

2、簡單複雜SQL的調用。有些一條SQL可能有好多行,通常都是一些報表。直接在JAVA或C程序調用並不方便,此時就可以創建一個視圖,然後就用一句簡單的“select * from 視圖名”就可以了。

3、實現相同查詢語句的複用。下面講一個需要統計數據出口的案例。假設大多數的業務都只針對本公司沒有離職的員工,每次查詢員工時都需要加上條件“where 離職狀態=0”,不方便,也容易因爲忘記加上條件而導致出錯。所以就可以建立一個視圖,這些業務每次查詢要處理的員工時,都從視圖中查詢。當需求改變時,如需要根據出生日期顯示員工年齡,也只需要改動視圖一處。

 

問題:如何創建、使用、刪除視圖?
回答:

創建視圖: create or replace view 視圖名 as select語句。“create or replace”表示的意思是同名的視圖沒有則創建,有則替換。

使用視圖:與表使用是完全一樣的,所以視圖也被當成一作“虛表”。

刪除視圖:drop view 視圖名。

問題:創建視圖時,提示“權限不夠”,怎麼辦?

解決:這是因爲scott沒有創建視圖的權限,解決方法見 這裏

 

問題:刪除視圖以後,原來表的數據刪除了沒有?
回答:

沒有,視圖中的查詢語句並沒有改變。相反地,如果原表中的數據發生改變,查詢視圖得到的數據也馬上會更新。

問題:視圖中是否保存了所查詢的數據?
回答:

沒有。視圖中只是保存了一條SQL語句,通過視圖所得到的數據,其實也就是查詢語句所返回的數據。

瞭解:Oracle中有一種物化視圖,可以將SQL所查詢的數據保存起來。缺點是對會降低數據庫增刪改的效率,因爲在原表數據發生變化時,數據庫必須同時更新物化視圖中的數據。

問題:通過視圖是否可以加快查詢速度?
回答:

不能。當數據量比較大,可以明顯感覺到通過視圖查詢的效率比直接執行SQL要低得多。要提高查詢的效率,最簡單的方法就是創建合理的索引。

問題:Oracle中可以通過視圖可以更新數據嗎?
回答:不一定。要取決於視圖中的sql語句。

示例一:可更新視圖。
create or replace view my_emp_view
as
select empno,ename,sal from emp;

--查詢視圖
select * from my_emp_view;

--更新視圖
update my_emp_view set sal=sal+100 where empno=7900;

可以執行。


示例二:不可更新視圖。
create or replace view my_emp_view
as
select deptno,count(*) as 人數 from emp
group by deptno;


--查詢視圖
select * from my_emp_view;

--更新視圖
update my_emp_view set 人數=人數+1
where deptno=10;

報錯:ORA-01732: 此視圖的數據操縱操作非法

邏輯上也說不通。上面的數據是數據庫計算出來的,也不可能被更新。


示例三:部分可更新視圖。
create or replace view my_emp_view
as
select d.deptno,d.dname,e.ename,e.empno
from dept d,emp e
where d.deptno=e.deptno

--查詢視圖
select * from my_emp_view;

--更新視圖
update my_emp_view set ename='張三' where empno=7900;
可以執行。

update my_emp_view set dname='市場部' where empno=7900;
不可以執行。因爲此時dname是通過表連接動態計算出來的。

分析:視圖能否更新,取決所更新的行是否能否實際的數據表中的行一一對應,如果能對應,則可以更新。emp表中的每一行數據與my_emp_view視圖中的每一行能夠一一對應,但是dept表中的每一行數據卻對應my_emp_view視圖的多行數據,所以在my_emp_view視圖中是不能更新部門信息的,但是能夠更新員工數據。


問題:如果有兩個人的姓名都叫“MIKE”,能不能更新呢?
回答:
肯定可以,因爲是根據empno進行更新的。

問題:如何才能通過視圖更新數據(my_emp_view例)?
回答:
在這個視圖上建立替代觸發器(在學習了觸發器以後才能看懂下面的內容)。
代碼:

create or replace trigger tr_emp_view
instead of update
on my_emp_view
for each row
declare
begin
update emp set ename = :new.ename
where empno = :new.empno;

update dept set dname = :new.dname
where deptno = :new.deptno;
end;

測試:
--更新視圖
update my_emp_view set ename='張三',dname='市場部'
where empno=7900;

可以執行,本質是上由觸發器同時對emp和dept表進行了修改。

--查詢視圖,發現原來“sale”全部變成了“市場部”。
select * from my_emp_view;

 

原文地址:http://hi.baidu.com/xydba/blog/item/78fb758a36f003fef01f3684.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章