SQL> create or replace view emp_x as select * from emp;
create or replace view emp_x as select * from emp
*
ERROR at line 1:
ORA-01031: insufficient privileges
SQL> conn /as sysdba
Connected.
SQL> grant create view to scott;
Grant succeeded.
SQL> conn scott/scott;
Connected.
SQL> create or replace view emp_x as select * from emp;
View created.
SQL> create table emp_x as select * from emp;
Table created.
SQL> create table dept_no as select * from dept;
Table created.
(1) 创建单表类型的视图
create or replace view v_emp as select ename,empno,sal from emp_x; --单表
select * from v_emp; --查询这个视图
(2) 创建有关联关系的视图
create or replace view v_emp_dept as
select a.ename,a.empno,a.sal,b.dname
from emp_x a,dept_no b
where b.deptno=a.deptno; --有关联关系的视图
select ename,empno from v_emp_dept;
(3) 需要注意视图字段的别名
视图中的字段如果是表达式或者是聚合函数组成的,必须写别名 as xxxx 否则报错:ORA-00998
create or replace view v_emp_dept_1
as select b.dname,count(a.empno),sum(a.sal),round(avg(a.sal))
from emp_x a,dept_no b
where a.deptno=b.deptno
group by b.dname;
as select b.dname,count(a.empno),sum(a.sal),round(avg(a.sal))
*
ERROR at line 2:
ORA-00998: must name this expression with a column alias
create or replace view v_emp_dept_1
as select b.dname,count(a.empno) as c1,sum(a.sal) as c2,round(avg(a.sal)) as c3
from emp_x a,dept_no b
where a.deptno=b.deptno
group by b.dname;
(4) 视图失效的处理
SQL> alter table dept_no rename to dept_x; --修改表的名字
Table altered.
SQL> select * from v_emp_dept;
select * from v_emp_dept
*
ERROR at line 1:
ORA-04063: view "SCOTT.V_EMP_DEPT" has errors --有错
SQL> select object_name,object_type,status from user_objects where object_name='V_EMP_DEPT';
OBJECT_NAME OBJECT_TYPE STATUS
-------------------- ------------------- -------
V_EMP_DEPT VIEW INVALID
发现视图无效,需要重新创建视图,将表名改为dept_x即可
(5) 在数据字典中查视图
SQL> select object_name,object_type,status from user_objects where object_name='V_EMP_DEPT';
OBJECT_NAME OBJECT_TYPE STATUS
-------------------- ------------------- -------
V_EMP_DEPT VIEW INVALID
select * from user_views --text字段存储视图的定义
SQL> select view_name,text from user_views;
VIEW_NAME TEXT
------------------------------ --------------------------------------------------------------------------------
V_EMP select ename,empno,sal from emp_x
V_EMP_DEPT select a.ename,a.empno,a.sal,b.dname
from emp_x a,dept_x b
where b.deptno=a.deptno
V_EMP_DEPT_1 select b.dname,count(a.empno) as c1,sum(a.sal) as c2,round(avg(a.sal)) as c3
from emp_x a,dept_x b
where a.deptno=b.deptno
group by b.dname
(6) 需要注意的三个问题
A 是否可以对视图做DML操作 --可以
B 对视图DML,执行成功,表的数据是否跟着变化 --会
update v_emp set sal=sal*1.2 where empno=7499;
commit;
select * from emp_x where empno=7499;
C 对有 聚合、分组操作、关联操作 的视图的DML操作分析 --都是不能够进行DML操作的
update v_emp_dept set sal=sal*1.2 where empno=7499; --有关联操作的视图是不能DML操作的
commit;
update v_emp_dept_1 set C3=2000 where dname='SALES'; --有聚合操作的视图不能DML
commit;
create or replace function get_sal_grade(v_sal in number) return number is
v number;
begin
select s.grade
into v
from salgrade s
where v_sal between s.losal and s.hisal;
return v;
exception when others then
return 0;
end;
创建一个视图
create or replace view v_emp_salgrd as
select a.ename,a.empno,a.sal,b.dname,get_sal_grade(a.sal) as salgrade
from emp a,dept b
where a.deptno=b.deptno;
SQL> conn hr/hr
Connected.
SQL> select * from scott.v_emp_salgrd;
select * from scott.v_emp_salgrd
*
ERROR at line 1:
ORA-00942: table or view does not exist --没有查询权限
(2) 授权
SQL> conn scott/scott;
Connected.
SQL> grant select on v_emp_salgrd to hr;
ENAME EMPNO SAL DNAME SALGRADE
---------- ---------- ---------- -------------- ----------
CLARK 7782 2450 ACCOUNTING 4
KING 7839 5000 ACCOUNTING 5
MILLER 7934 1300 ACCOUNTING 2
JONES 7566 2975 RESEARCH 4
FORD 7902 3000 RESEARCH 4
ADAMS 7876 1100 RESEARCH 1
SMITH 7369 800 RESEARCH 1
SCOTT 7788 3000 RESEARCH 4
WARD 7521 1250 SALES 2
TURNER 7844 1500 SALES 3
ALLEN 7499 1600 SALES 3
JAMES 7900 950 SALES 1
BLAKE 7698 2850 SALES 4
MARTIN 7654 1250 SALES 2
14 rows selected.
思考一个问题
上面的视图里面有函数,我们能够利用视图对函数有查的权限,此时是否对SCOTT用户下函数有执行的权限??
SQL> select scott.get_sal_grade(3500) from dual;
select scott.get_sal_grade(3500) from dual
*
ERROR at line 1:
ORA-00904: : invalid identifier --没有使用函数的权限
跨用户查询视图,发起者是HR,执行者是SCOTT用户,而不是HR在执行
SQL> conn scott/scott
Connected.
SQL> grant execute on get_sal_grade to hr; --跨用户执行SP、FUN、PKG,必须授予execute on xxxx to yyy
Grant succeeded.
SQL> conn hr/hr
Connected.
SQL> select scott.get_sal_grade(3500) from dual;
truncate表的权限:必须要授予 drop any table,但是这个权限太大,不允许这样做的。
drop table -- 仅仅可以删除本用户下的表
drop any table -- 可以删除数据库上所有的表
现象:
SQL> conn hr/hr
Connected.
SQL> truncate table scott.emp_x;
truncate table scott.emp_x
*
ERROR at line 1:
ORA-00942: table or view does not exist --没法进行操作
SQL> conn /as sysdba
Connected.
SQL> grant drop any table to hr; --授权,但是权限太大
SQL> conn /as sysdba
Connected.
SQL> revoke drop any table from hr; --取消权限
Revoke succeeded.
SQL> truncate table scott.emp_x;
truncate table scott.emp_x
*
ERROR at line 1:
ORA-00942: table or view does not exist
解决方案:
在SCOTT下创建一个存储过程
create or replace procedure truncate_tab is
v_tab varchar2(100);
begin
v_tab:='emp_x';
execute immediate 'truncate table scott.'||v_tab; --在存储过程中调用DDL必须用execute immediate
exception when others then
dbms_output.put_line(sqlerrm);
end;
SQL> conn scott/scott;
Connected.
SQL> set serveroutput on 在sqlplus中执行PL SQL的命名块,存储过程必须把这一项打开
SQL> insert into emp_x select * from emp;
create or replace package Nocopypkg is
type arr is varray(1000000) of hrc_tab%rowtype; --创建一个数组,类型为行变量
procedure p1(ip1 in out arr);
procedure p2(ip2 in out nocopy arr);
function get_time return number;
end Nocopypkg;