视图

oracle212


视图

q视图以经过定制的方式显示来自一个或多个表的数据
q视图可以视为“虚拟表”或“存储的查询”
q创建视图所依据的表称为“基表”
q视图的优点有:
q提供了另外一种级别的表安全性
q隐藏的数据的复杂性
q简化的用户的SQL命令
q隔离基表结构的改变
q通过重命名列,从另一个角度提供数据

创建视图语法 :
CREATE [OR REPLACE] [FORCE]VIEW

view_name [(alias[, alias]...)]

AS

select_statement

[WITH CHECK OPTION]

[WITH READ ONLY];

SQL> create view test_view_force as select * from student;
create view test_view_force as select * from student
ORA-00942: 表或视图不存在

SQL> create force view test_view_force as select * from student;
Warning: View created with compilation errors

SQL> select * from user_views uv where uv.VIEW_NAME='TEST_VIEW_FORCE';
VIEW_NAME TEXT_LENGTH TEXT TYPE_TEXT_LENGTH TYPE_TEXT OID_TEXT_LENGTH OID_TEXT VIEW_TYPE_OWNER VIEW_TYPE SUPERVIEW_NAME EDITIONING_VIEW READ_ONLY
------------------------------ ----------- -------------------------------------------------------------------------------- ---------------- -------------------------------------------------------------------------------- --------------- -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ------------------------------ --------------- ---------
TEST_VIEW_FORCE 22 select * from student N N

SQL> SELECT * FROM TEST_VIEW_FORCE;
SELECT * FROM TEST_VIEW_FORCE
ORA-04063: view "HR.TEST_VIEW_FORCE" 有错误

SQL> create table student(id number(20),name varchar2(20), enter_date date );
Table created
SQL> insert into student values(1,'张三',to_date('20140101','yyyymmdd'));
1 row inserted

SQL> insert into student values(1,'李四',to_date('20140102','yyyymmdd'));
1 row inserted

SQL> insert into student values(1,'王五',to_date('20140103','yyyymmdd'));
1 row inserted

SQL>
SQL> select * from test_view_force;
ID NAME ENTER_DATE
--------------------- -------------------- -----------
1 张三 01-1月-14
1 李四 02-1月-14
上面的测试时针对于force关键字的,通过force关键字可以预先为某个即将创建的表先创建视图。

SQL> create view test_view_with_check_option as select * from student where student.name='张三';
View created

SQL> select * from test_view_with_check_option;
ID NAME ENTER_DATE
--------------------- -------------------- -----------
2 张三 01-1月-14

SQL> update test_view_with_check_option tvwco set tvwco.ID=10 where tvwco.NAME='张三';
1 row updated

SQL> select * from test_view_with_check_option;
ID NAME ENTER_DATE
--------------------- -------------------- -----------
10 张三 01-1月-14

SQL> select * from student;
ID NAME ENTER_DATE
--------------------- -------------------- -----------
10 张三 01-1月-14
4 李四 02-1月-14
4 王五 03-1月-14

SQL>
更新视图也更新表
上面的测试本来是验证假如没有加with check option就会出现 红色的查询会查不出来,会出现丢失行的问题
但是测试没有成功....反正记住这一点加了with check option就是为了视图不能更新

with reed only 不能更新

视图的DML:
q在视图上也可以使用修改数据的DML语句,如INSERT、UPDATE和DELETE
q视图上的DML语句有如下限制:
q只能修改一个底层的基表
q如果修改违反了基表的约束条件,则无法更新视图
q如果视图包含连接操作符、DISTINCT 关键字、集合操作符、聚合函数或 GROUP BY 子句,则将无法更新视图
q如果视图包含伪列或表达式,则将无法更新视图

键保留表:
定义:就是两个表建立复杂视图,在视图中充当主键的列是来自哪个表中的那么那张表就是键保留表,相反的为非键保留表
对于键保留表通过视图可以更新,而对于非键保留表不可以通过视图更新;也就是视图中的列是来自键保留表中的列可以更新,相反的则不能。
但是可以通过instead of 触发器可以做到非保留表的更新操作
SQL> purge recyclebin;//清除回收站
Done

SQL> create table student (sno number(20),sname varchar2(20),sdept number(20));
Table created

SQL> create table dept (deptno number(20),deptname varchar2(20));
Table created

SQL> insert into student values(1,'张三',100);
1 row inserted

SQL> insert into student values(2,'李四',101);
1 row inserted

SQL> insert into student values(3,'李四',102);
1 row inserted

SQL> insert into dept values(100,'数计系');
1 row inserted

SQL> insert into dept values(101,'医学系');
1 row inserted

SQL> insert into dept values(102,'文学系');
1 row inserted

SQL> alter table student add constraints pk_student primary key(sno);
Table altered

SQL> alter table dept add constraints pk_dept primary key(deptno);
Table altered
SQL>
SQL> alter table student add constraints fk_foreign foreign key(sdept) references dept(deptno);
Table altered

SQL> create view view_stu_dept
2 as
3 select * from student s inner join dept d on s.sdept = d.deptno;
View created

SQL> select * from view_stu_dept;
SNO SNAME SDEPT DEPTNO DEPTNAME
--------------------- -------------------- --------------------- --------------------- --------------------
1 张三 100 100 数计系
2 李四 101 101 医学系
3 李四 102 102 文学系

SQL> select uc.OWNER,uc.CONSTRAINT_NAME,uc.CONSTRAINT_TYPE,uc.TABLE_NAME,uc.view_related from user_constraints uc where uc.TABLE_NAME='STUDENT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME VIEW_RELATED
------------------------------------------------------------ ------------------------------ --------------- ------------------------------ --------------
HR PK_STUDENT P STUDENT
HR FK_FOREIGN R STUDENT


SQL> update view_stu_dept vsd set vsd.SNO=11 where vsd.SNO = 1;
1 row updated

SQL> select * from student;
SNO SNAME SDEPT
--------------------- -------------------- ---------------------
11 张三 100
2 李四 101
3 李四 102

SQL> update view_stu_dept vsd set vsd.SDEPT=103 where vsd.SNO = 2;
update view_stu_dept vsd set vsd.SDEPT=103 where vsd.SNO = 2
ORA-02291: 违反完整约束条件 (HR.FK_FOREIGN) - 未找到父项关键字

SQL> update view_stu_dept vsd set vsd.DEPTNO=103 where vsd.SNO = 2;
update view_stu_dept vsd set vsd.DEPTNO=103 where vsd.SNO = 2
ORA-01779: 无法修改与非键值保存表对应的列

SQL>

视图中使用函数:
q视图中可以使用单行函数、分组函数和表达式
q必须为使用函数或者表达式的字段指定名字
SQL> create view view_stu_fun
2 as
3 select sno, upper(student.sname) ,student.sdept from student s ;
create view view_stu_fun
as
select sno, upper(student.sname) ,student.sdept from student s
ORA-00904: "STUDENT"."SDEPT": 标识符无效
上面错误说明了假如给表起了别名那么就必须使用指定别名来引用列而不能使用 表名.列名
SQL>
SQL> create view view_stu_fun
2 as
3 select sno, upper(student.sname) ,student.sdept from student
4
SQL> create view view_stu_fun
2 as
3 select sno ,upper(sname),sdept from student;
create view view_stu_fun
as
select sno ,upper(sname),sdept from student
ORA-00998: 必须使用列别名命名此表达式
使用函数创建视图必须为视图起别名

SQL> create view view_stu_fun
2 as
3 select sno ,upper(sname) as upper_sname,sdept from student;
View created

SQL> select * from student;
SNO SNAME SDEPT
--------------------- -------------------- ---------------------
1 zhangsan 100
2 李四 101
3 李四 102

SQL> select * from view_stu_fun;
SNO UPPER_SNAME SDEPT
--------------------- -------------------- ---------------------
1 ZHANGSAN 100
2 李四 101
3 李四 102

SQL> update view_stu_fun set UPPER_SNAME = '张三' where UPPER_SNAME='zhangsan';
update view_stu_fun set UPPER_SNAME= '张三' where UPPER_SNAME='zhangsan'
ORA-01733: 此处不允许虚拟列
更新视图时不能使用虚拟列

SQL> update view_stu_fun set SNO = 4 where UPPER_SNAME='ZHANGSAN';
1 row updated

SQL>
SQL> create view view_stu_fun_2
2 as
3 select sno as snoo, upper(student.sname) as upper_sname,student.sdept from student;
View created

SQL> select * from view_stu_fun_2;
SNOO UPPER_SNAME SDEPT
--------------------- -------------------- ---------------------
4 ZHANGSAN 100
2 李四 101
3 李四 102

SQL> update view_stu_fun_2 set snoo=5 where snoo = 4;
1 row updated

SQL> update view_stu_fun_2 set UPPER_SNAME='张三' where snoo = 5;
update view_stu_fun_2 set UPPER_SNAME='张三' where snoo = 5
ORA-01733: 此处不允许虚拟列

SQL>
SQL> select * from view_stu_fun_2;
SNOO UPPER_SNAME SDEPT
--------------------- -------------------- ---------------------
5 ZHANGSAN 100
2 李四 101
3 李四 102

SQL> update view_stu_fun_2 set snoo=7 where UPPER_SNAME = 'ZHANGSAN';
1 row updated

SQL>
对于上面的更新只能更新视图中没有被函数处理的列,但是where 子句中可以使用被函数处理的列










你可能感兴趣的:(视图)