oracle实战3(视图)

####################################################################################
创建和使用视图
####################################################################################

# 视图

在Oracle中有4种视图:
1、关系视图
2、内嵌视图
3、对象视图
4、物化视图

视图的作用:
1、强化安全
2、增强性能
3、隐藏复杂性
4、提供抽象
5、定制数据表示

conn oe/oe@test;

create view company_phone_book
as
select last_name ||','||first_name name,phone_number,email
from employees;

select name,phone_number from company_phone_book;


desc user_views;

select text from user_views where view_name='COMPANY_PHONE_BOOK';

CREATE OR REPLACE VIEW company_phone_book
as
select employee_id emp_id,last_name ||','||first_name name,phone_number,email
from employees;

# 建立视图

例1:为表emp建立视图dept20,此视图可以显示部门20的雇员和他们的年薪。

Create view dept20
As
select ename,deptno,job, sal*12 sal12
From emp where deptno=20;

例2:

Create view clerk (id_number, person, depart, position )
As select empno,ename,deptno,job
From emp where job='CLERK'
With check option constraint wco;

用户不能往clerk视图中作insert(或update)非'clerk'的记录。

insert into clerk values(7999,'angeos',10,'CLERK');

select * from clerk;

select empno,ename,deptno from emp where deptno=10;

insert into clerk values(7998,'angeos',10,'Manager');
提示插入的数据违反了WITH CHECK OPTION约束。

# 删除视图

drop view view_name;

# 视图中的约束

create view emps_hired_in_2000 as
select * from employees
where to_char(hire_date,'YYYY')='2000';

select count(*) from emps_hired_in_2000;

create view yearly_hire_totals as
select to_char(hire_date,'YYYY') year,count(*) total
from employees
group by to_char(hire_date,'YYYY')
order by to_char(hire_date,'YYYY');

select * from yearly_hire_totals;

# 试验:约束和安全

假设我们建立一个视图,这个视图可以基于用户的身份进行查询约束。在HR模式中使用
employees表时,我们注意到用户的EMAIL列,假设这一列不仅仅存放的是用户的EMAIL,
而且也是他们的数据库登录ID。
我们研究下面的问题:

首先以管理员身份登录:
conn sys/sysadmin@test as sysdba;
alter user hr account unlock;
alter user hr identified by hr;

然后以hr登录,建立视图:

create or replace view my_reports as
select last_name,first_name
from employees
where manager_id=(
select employee_id from employees
where email=user);

授权:

grant select on my_reports to public;

查询视图:
show user;
可以看到用户为HR
查询视图:
select * from my_reports;
无返回结果。???

由于HR不是雇员,所以,不会有结果返回。

以管理员身份登录数据库,创建用户SKING,他是公司的经理,并且使用SKING作为他的
电子邮件地址(假设):

conn sys/sysadmin@keymen as sysdba;

create user sking identified by sking;

grant connect,resource to sking;

以新用户身份登录,查询视图:

conn sking/sking@keymen;

select * from hr.my_reports;
这次有返回结果。

由于视图的所有者是HR,所以我们需要在视图名称前加上模式限定。

# 联接视图

在HR模式中,我们查看一张视图:

desc EMP_DETAILS_VIEW;

set long 5000;

select text from user_views
where view_name='EMP_DETAILS_VIEW';

通过查询,我们看到这个视图联接了六张表。而且视图定义的末尾处,WITH READ ONLY选项
表明了,这个视图是只读视图。INSERT、UPDATE和DELETE语句都不能对这个视图执行。


# 验证视图

conn scott/tiger@test;

create table t(
id number,
data varchar2(20)
);

create view view_t as
select id view_id,data view_data
from t;


insert into t values(1,'ABC');
select * from view_t;

alter table t
modify(id number,data varchar2(255));

alter table t
add(data2 varchar2(100));

desc t;

select object_name,status
from user_objects
where object_name='VIEW_T';

你会发现视图无效了。!!!

select * from view_t;
你会发现可以查到数据了。Oracle对视图进行了重新编译处理!

我们也可以手工处理:
alter view view_t compile;



####################################################################################
创建和使用内嵌视图
####################################################################################

# 内嵌视图严格的来说不是模式对象,即它与普通关系视图不同。从根本上来讲,内嵌视图就是嵌入到父查询中的查询,能够
在任何可以使用表名称的地方使用。内嵌视图可以出现在SELECT语句的FROM子句中,以及INSERT
INTO、UPDATE,甚至是DELETE FROM语句中。
内嵌视图是临时的--他只存在于父查询的运行期间,但是它可以让开发者有能力在整个查询的
任何部分中使用视图结果。

# 建立内嵌视图

conn hr/hr@keymen;

select department_name,count(*),to_char((count(*)/total_emp.cnt)*100,'90.99')||'%'
pct from departments,employees,
(select count(*) cnt from employees) total_emp
where departments.department_id = employees.department_id
group by department_name,total_emp.cnt;

工作原理:
为了计算各个部门雇佣工作人员的比例,我们需要两部分信息。首先,我们需要雇员的整体
数量,通过语句获得:
select count(*) from employees;

其次:我们需要各个部门中雇员得数量:
select department_name,count(*)
from departments,employees
where departments.department_id = employees.department_id
group by department_name;

我们需要建立一个计算雇员整体数量得内嵌视图。

(select count(*) cnt from employees) total_emp;

整体描述:

select department_name,count(*),to_char((count(*)/total_emp.cnt)*100,'90.99')||'%'
pct from departments,employees,
(select count(*) cnt from employees) total_emp;

# 试验:谁是公司得前5名员工?

select last_name,hire_date from employees
order by hire_date;

select last_name,hire_date from employees
where rownum<6
order by hire_date;



select last_name,hire_date
from (select last_name,hire_date from employees order by hire_date)
where rownum<=5;


####################################################################################
创建和使用对象视图
####################################################################################

# 对象视图
Oracle是面向对象的数据库产品。随着Oracle8i的出现,Oracle融入了两个概念,进而
可以让开发者建立对象类型、建立这种类型的对象,并且在数据库表中存储对象实例。

# 试验:建立对象视图

create type employee_type is object(
employee_id number,
name varchar2(47),
email varchar(25),
phone_number varchar2(20)
);

create view ov_company_phone_book of employee_type
with object oid(employee_id) as
select e.employee_id,e.last_name ||','||e.first_name,
e.email,e.phone_number
from employees e;

desc ov_company_phone_book;

select view_type_owner,view_type,oid_text
from user_views
where view_name='OV_COMPANY_PHONE_BOOK';





####################################################################################
创建和使用物化视图
####################################################################################

# 物化视图

conn oe/oe@keymen;

desc orders;

select count(*) from orders;

create table my_orders as
select * from orders;

insert into my_orders
select * from my_orders;

执行对次,使得表中有107520行数据。

select count(*) from my_orders;


@ c:\oracle\ora92\rdbms\admin\utlxplan.sql;
CONN sys/sysadmin@keymen as sysdba;
@ c:\oracle\ora92\sqlplus\admin\plustrce.sql;

grant plustrace to public; --授权任何用户都可以执行查询计划



对Oracle 10g数据库

@ C:\oracle\product\10.2.0\db_1\RDBMS\ADMIN\utlxplan.sql;

@ C:\oracle\product\10.2.0\db_1\sqlplus\admin\plustrce.sql;
grant plustrace to public; --授权任何用户都可以执行查询计划

set autotrace on;
set timing on;
select customer_id,count(*) total_orders
from my_orders
group by customer_id;

建立物化视图

set timing off;
create materialized view my_orders_mv2
build immediate
refresh on commit
enable query rewrite
as
select customer_id,count(*) total_orders
from my_orders
group by customer_id;

set timing on;
select * from my_orders_mv2;

通过对比发现,在my_orders视图中,通过1000多次计算才得出结果,而在my_orders_mv
视图中,只计算了不到10次就获得了结果,查询的性能得到了极大的优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值