视图
视图
什么是视图?
视图是用户所看到的图像,这个图像并不是真正的数据。是经过转换后的一种数据表示。
为什么引入视图?
维护数据的独立性。
什么是数据的独立性呢?
早期的信息系统的设计与开发多采用模块驱动方式,即设计与开发者首先根据用户的需求建立功能模块(过程和函数),再由这些模块来决定结构和存储。以这种方法设计和开发的信息系统在绝大多数情况下是很难维护的。
面对变化是不可避免这一事实时,设计与开发者如何才能设计和开发出相对稳定的信息系统呢?即信息系统的某一局部变化时,不需要修改相应的数据结构和数据存储。。研究表明:虽然随着用户的需求变化,模块的变化几乎是不可避免的,但是信息系统中的数据却几乎是不变的(数据的排列可能会变化)。这样的发现就导致了一种与与模块驱动方式完全不同的信息系统设计与开发方法的诞生,这种信息系统设计与开发的方法就叫做数据驱动法。

使用视图的好处:
把复杂的SQL简单化,复杂逻辑放在了创建视图的过程中
限制数据库的访问,通过视图可以访问的列必须是视图中有的
使数据独立于应用程序
可以使得相同的数据以不同的形式出现在不同的视图中
如何创建视图:
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW 视图名
[(别名[,别名]...)]
AS
子查询语句
[WITH CHECK OPTION[CONSTRAINT 约束名]]
[WITH READ ONLY]
其中每个选项的含义如下:
OR REPLACE:如果创建的视图已经存在,Oracle系统会重建这个视图
FORCE: 不管所引用的表是否存在,Oracle系统都会创建这个视图
NOFORCE:只有当所引用的表都存在时,Oracle系统才会重建这个视图(这是Oracle系统的默认方式)
视图名:要创建的视图的名字
别名:为视图所产生的列的定义的别名(别名的个数一定要和视图所产生的烈数相等)
子查询语句:一个完整的查询语句
WITH CHECK OPTION: 所插入或修改的额数据必须满足视图所定义的约束条件
约束名:WITH CHECK OPTION中的约束名
WITH READ ONLY:保证在该视图上不能进行任何DML操作
需要注意的而是:在子查询语句中不能包含ORDER BY子句
例子:
CREATE OR REPLACE VIEW acct
("名字","工资","职位","雇用日期")
AS
SELECT ename, sal, job, hiredate
FROM emp
WHERE deptno = 10;
我们在视图中为视图每一列都使用了别名。这是为什么?
1、一般表时IT人员使用的,为了减少输入的次数,表的设计者们一般倾向于用缩写形式来表示表名和列名。但是视图就不一样了,一般是与时非IT专业人员使用的,这是如果再用缩写形式会令人望而生畏。所以视图一般用用户熟知的名字。
2.一般表名和列名都是ASCII定义的,在视图中应该改为用户熟知的别名(一般用本国语言),可以增加易读性
SELECT *
FROM acct;
如何修改视图:
Oracle并没有直接提供修改视图的方法。如果您想修改一个已经存在的视图的话,您应该利用创建语句将原来的视图覆盖掉
CREATE OR REPLACE VIEW acct
("名字","工资","职位","雇用日期","部门","地点")
AS
SELECT ename, sal, job, hiredate, dname, loc
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND emp.deptno = 10;
Oracle系统如何管理视图
通过数据字典user_views得到这方面的信息
SELECT view_name, text_length, text
FROM user_views;
上面的例子可以看出,一旦您创建了一个视图之后,您就可以像使用表一样对它进行查询,其实从实用的角度来看,视图和表几乎没有什么区别。那么当您使用视图来进行查询时,Oracle系统又是如何工作的饿呢?
1、从数据字典中取出视图的定义,即查询语句
2、检查该视图所引用的表的权限
3、执行视图所定义的查询语句
可以看出,使用视图访问数据库时,至少需要两次访问磁盘(第一次访问数据字典,第二次访问表中的数据),可能带来一些效率问题。
如何使用视图(Views)来进行DML操作
视图的分类:简单视图和复杂视图。
它们的定义如下:
简单视图:
数据仅仅从一个表中提取
不包含函数
不包含分组数据
可以通过该视图进行DML操作
复杂视图:
数据是从多个表中提取
包含函数
包含分组数据
不一定能够通过该视图进行DML操作
虽然您可以通过视图进行DML操作,但是Oracle加上了许多限制。实际上在视图上进行的DML操作都要转换成对所引用的表的DML操作。所有通过视图进行DML操作的规则如下:
可以在简单视图上执行DML操作
如果在一个视图中包含了分组函数或者GROUP BY 子句,或者DISTINCR关键字,就不能通过该视图进行DELETE操作
如果再一个视图中包含了分组函数,或GROUP BY子句,或DISTINCT关键字,就不能对视图进行UPDATE操作
如果再一个视图中包含了由表达式组成的列或者伪列ROWNUM,就也不能通过该视图进行修改操作
如果在一个视图中包含了分组函数或GROUP BY子句,或者DISTINCT关键字,就不能通过该视图进行插入操作
如果再一个视图中包含了由表达式组成的列或者伪列ROWNUM,就也不能通过该视图进行插入操作
如果一个视图没有包含引用表中哪些不能为NULL的列,也就不能通过该视图进行插入操作
怎样使用视图的WITH CHECK OPTION子句
CREATE VIEW sales30
AS
SELECT *
FROM emp
WHERE deptno = 30
WITH CHECK OPTION CONSTRAINT sale30_ck;
视图中的WITH CHECK OPTION CONSTRAINT子句的含义是:所有通过该视图进行的DML操作都不能违反了在创建视图中用的where子句所限定的条件
使用WITH READ ONLY子句
CREATE OR REPLACE VIEW acct
("名字","工资","职位","雇用日期","部门","地点")
AS
SELECT ename, sal, job, hiredate, dname, loc
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND emp.deptno = 10
WITH READ ONLY;
在创建视图时应该尽可能使用WITH READ ONLY子句。这样可以避免许多因DML误操作对真正表的破坏。
如何删除视图:
DROP VIEW 视图名 删除视图不会影响表对象
DROP VIEW acct;
内嵌视图(Inline Views)
内嵌视图是一种比较复杂但却很有用的结构
SELECT e.empno, e.ename, e.job, m.empno, m.ename, m.job
FROM emp_shell e, e_m_shell, (SELECT empno, enamem job
FROM emp) m
WHERE e.empno = e_m_shell.e_id
AND e_m_shell.m_id = m.empno;
查询语句中m就是内嵌视图的名字,当您定义了内嵌视图之后,就可以像表或者视图一样使用这个内嵌视图。其中视图名就是您所定义的视图名,列名就是您再子查询语句SELECT子句中所使用的列名
注意:内嵌视图不属于任何用户,也不是对象
内嵌视图主要用在前n行查询/分析中(Top n queries/analysis)
前n行查询/分析(Top n queries/analysis)
语法:
SELECT ROWNUM, [列名[, 列名...]]
FROM ([列名 [, 列名]]
FROM 表名
ORDER BY "Top n 列名")
WHERE ROWNUM <= N;
子查询或内嵌视图将产生一个数据的存储列表。为了保证存储列表中的数据按照所需要的顺序排列,要在子查询或者内嵌式视图中包含ORDER BY子句。
例子:
SELECT rownum "Order NO", ename "Name", sal "Salary", job "Job"
FROM (SELECT ename, sal, job
FROM emp
WHERE job NOT LIKE 'PRESI%'
ORDER BY sal DESC)
WHERE ROWNUM <= 5 ;

浙公网安备 33010602011771号