《view篇》
什么是视图
视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的。视图只有逻辑定义。每次使用的时候,只是重新执行SQL。
当通过视图修改数据时,实际上是在改变基表中的数据;相反地,基表数据的改变也会自动反映在由基表产生的视图中。由于逻辑上的原因,有些Oracle视图可以修改对应的基表,有些则不能(仅仅能查询)。
tips: 查询视图没有什么限制, 插入/更新/删除视图的操作会受到一定的限制; 所有针对视图的操作都会影响到视图的基表; 为了防止用户通过视图间接修改基表的数据, 可以将视图创建为只读视图(带上with read only选项)
创建视图
1 权限:
要在当前方案中创建视图, 用户必须具有create view系统权限; 要在其他方案中创建视图, 用户必须具有create any view系统权限. 视图的功能取决于视图拥有者的权限.
2 语法:
create [ or replace ] [ force ] view [schema.]view_name
[ (column1,column2,...) ]
as
select ...
[ with check option ]
[ constraint constraint_name ]
[ with read only ];
tips:
1 or replace: 如果存在同名的视图, 则使用新视图"替代"已有的视图
2 force: "强制"创建视图,不考虑基表是否存在,也不考虑是否具有使用基表的权限
3 column1,column2,...:视图的列名, 列名的个数必须与select查询中列的个数相同; 如果select查询包含函数或表达式, 则必须为其定义列名.此时, 既可以用column1, column2指定列名, 也可以在select查询中指定列名.
4 with check option: 指定对视图执行的dml操作必须满足“视图子查询”的条件即,对通过视图进行的增删改操作进行"检查",要求增删改操作的数据, 必须是select查询所能查询到的数据,否则不允许操作并返回错误提示. 默认情况下, 在增删改之前"并不会检查"这些行是否能被select查询检索到.
5 with read only:创建的视图只能用于查询数据, 而不能用于更改数据.
6 alter view 视图名 compile,当视图依赖的基表改变后,视图会“失效”。为了确保这种改变“不影响”视图和依赖于该视图的其他对象,应该使用 alter view 语句“明确的重新编译”该视图,为了重新编译其他模式中的视图,必须拥有alter any table系统权限。注意:当访问基表改变后的视图时,oracle会“自动重新编译”这些视图。
7 查看视图,使用数据字典视图
1 dba_views——DBA视图描述数据库中的所有视图
2 all_views——ALL视图描述用户“可访问的”视图
3 user_views——USER视图描述“用户拥有的”视图
4 dba_tab_columns——DBA视图描述数据库中的所有视图的列(或表的列)
5 all_tab_columns——ALL视图描述用户“可访问的”视图的列(或表的列)
6 user_tab_columns——USER视图描述“用户拥有的”视图的列(或表的列)
3.1 创建简单视图
简单视图定义:是指基于单个表建立的,不包含任何函数、表达式和分组数据的视图。
SQL> conn /as sysdba
Connected.
SQL> grant create view to scott;
SQL> conn scott/tiger
Connected.
SQL> create view vw_emp as select empno,ename,job,hiredate,deptno from emp;
SQL> desc vw_emp
Name Null? Type
------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
HIREDATE DATE
DEPTNO NUMBER(2)
SQL> select * from vw_emp where deptno=10;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- ---------
7782 CLARK MANAGER 09-JUN-81 10
7839 KING PRESIDENT 17-NOV-81 10
7934 MILLER CLERK 23-JAN-82 10
对简单视图进行DML操作
SQL> insert into vw_emp values(1,'a','aa','05-JUN-88',10);
SQL> update vw_emp set ename='cc' where ename='KING';
SQL> delete vw_emp where ename='cc';
SQL> select * from vw_emp where deptno=10;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7782 CLARK MANAGER 09-JUN-81 10
7934 MILLER CLERK 23-JAN-82 10
1 a aa 05-JUN-88 10
基表也发生了相应的更改
SQL> select empno,ename,job,hiredate,deptno from emp where deptno=10;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7782 CLARK MANAGER 09-JUN-81 10
7934 MILLER CLERK 23-JAN-82 10
1 a aa 05-JUN-88 10
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ -------------------
VW_EMP VIEW
SALGRADE TABLE
BONUS TABLE
PK_EMP INDEX
EMP TABLE
DEPT TABLE
PK_DEPT INDEX
7 rows selected.
创建只读视图with read only
SQL> create view vw_emp_readonly as select empno,ename,job,hiredate,deptno from emp with read only;
SQL> select * from vw_emp_readonly where deptno=10;
EMPNO ENAME JOB HIREDATE DEPTNO
---------- ---------- --------- --------- ----------
7782 CLARK MANAGER 09-JUN-81 10
7934 MILLER CLERK 23-JAN-82 10
1 a aa 05-JUN-88 10
只能查询,无法进行更改
SQL> delete vw_emp_readonly where empno=1;
delete vw_emp_readonly where empno=1
*
ERROR at line 1:
ORA-42399: cannot perform a DML operation on a read-only view
创建检查约束视图with check option
Sql>create view vw_emp_check as select empno,ename,job,hiredate,deptno from emp where deptno=10 with check option;
SQL> insert into vw_emp_check values('2','c','cc','02-JAN-55',10);
SQL> insert into vw_emp_check values('3','d','dd','02-JAN-65',20);
insert into vw_emp_check values('3','d','dd','02-JAN-65',20)
*
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation
创建检查视图:对通过视图进行的增删改操作进行检查,要求增删改操作的数据必须是select查询所能查询到的数据
20号部门不在查询范围内,违反检查约束,所以无法插入;
SQL> delete vw_emp_check where empno=2;
1 row deleted.
--所删除的数据在查询范围内,不违反检查约束
3.2 连接视图
3.2.1 连接视图定义:
是指基于多个表所创建的视图,即,定义视图的查询是一个连接查询。 主要目的是为了简化连接查询;
3.2.2 创建连接视图
示例1: 查询部门编号为10和30的部门及雇员信息
SQL> create view vw_dept_emp
as select a.deptno,a.dname,a.loc,b.empno,b.ename,b.sal from dept a,emp b where a.deptno=b.deptno and a.deptno in(10,30);
View created.
3.2.3 连接视图上的DML操作
SQL> insert into vw_dept_emp values(10,'aaa','aaaa',22,'a',5000);
insert into vw_dept_emp values(10,'aaa','aaaa',22,'a',5000)
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table
在视图上进行的所有DML操作,最终都会在基表上完成;
select 视图没有什么限制,但insert/delete/update有一些限制;
3.2.4键值保存表
如果连接视图中的一个“基表的键”(主键、唯一键)在它的视图中仍然存在,并且“基表的键”仍然是“连接视图中的键”(主键、唯一键);即,某列在基表中是主键|唯一键,在视图中仍然是主键|唯一键,则称这个基表为“键值保存表”。
一般地,由主外键关系的2个表组成的连接视图,外键表就是键值保存表,而主键表不是。
3.2.5 连接视图的更新准则
一:一般准则——(讲)
1任何DML操作,只能对视图中的键值保存表进行更新, 即,“不能通过连接视图修 改多个基表”;
2在DML操作中,“只能使用连接视图定义过的列”;
3“自连接视图”的所有列都是可更新(增删改)的
二:insert准则
1 在insert语句中不能使用“非键值保存表”中的列(包括“连接列”);
2 执行insert操作的视图,至少应该“包含”键值保存表中所有设置了约束的列;
3 如果在定义连接视图时使用了WITH CHECK OPTION 选项,则“不能”针对连接视 图执行insert操作
三:update准则
1键值保存表中的列是可以更新的;
2如果在定义连接视图时使用了WITH CHECK OPTION 选项,则连接视图中的连接列(一般就是“共有列”)和基表中的“其他共有列”是“不可”更新的,连接列和共有列之外的 其他列是“可以”更新的
四:delete准则
1如果在定义连接视图时使用了WITH CHECK OPTION 选项,依然“可以”针对连接视图执行delete操作
3.2.6 可更新连接视图
如果创建连接视图的select查询“不包含”如下结构,并且遵守连接视图的“更新准则”,则这样的连接视图是“可更新”的:
- 一:集合运算符(union,intersect,minus)
- 二:DISTINCT关键字
- 三:GROUP BY,ORDER BY,CONNECT BY或START WITH子句
- 四:子查询
- 五:分组函数
- 六:需要更新的列不是由“列表达式”定义的
- 七:基表中所有NOT NULL列均属于该视图
报错:创建视图view 权限不足,无法创建
创建视图权限,只授权第一个是无法创建 视图的,需要三个权限都授予
授权使用系统管理员登陆数据库:
账号:system
密码:manage
B(用户)
-–授予创建视图权限
grant create view to B;
–-授予查询权限
grant select any table to B;
-–授予权限
grant select any dictionary to B;
报错:view错误ORA-04063
原文链接:https://blog.csdn.net/weixin_39750084/article/details/80978702
错误ORA-04063:view view_test has errors
这个错误发生的原因有两种情况:
1、
一种是创建的视图本身有误,但是通过force等命令强制创建成功了,比如视图本身包含基表中不存在的列(或者是基于不存在的列使用了分析函数创造的列)。
解决方案:
最好不要用强制方法创建视图,保证所用的列都是真实存在的!
2、
视图的基表,或者视图基于其创建的视图被删除了。Oracle中的视图可能会先被创建了,然后其基表或者视图被删除了,就会导致当前视图产生错误。比如为了避免使用占空间较多的临时表,我使用了很多视图,然后通过视图来实现复杂的取数,但我在删除视图的过程中,是按创建视图的顺序从前往后删除的。先删除的最后一个视图生成时用到过的视图,这就会导致最后一个生成的视图是基于不存在的视图产生的,从而是个错误视图,不能查询。
解决方案:
所以在删除视图时,要非常注意删除的顺序,最后需要用到的数据,最好是从视图里复制到有物理存储空间的表中,再逆序删除所有的临时视图。