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

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