SQL 基础--> 视图(CREATE VIEW)

系统 1358 0

--================================

-- SQL 基础 --> 视图 (CREATE VIEW)

--================================

 

视图:

    从表中抽出来的逻辑上相关的数据集合

    视图其实就是一条查询 SQL 语句,用于显示一个或多个表或其它视图中相关数据。

    视图将查询的结果作为一个表来使用,因此视图可以被看作是存储的查询或一个虚拟表

    视图来源于表,所有对视图数据的修改最终都会被反映到视图的基表中,这些修改必须服从基表的完整性约束,并同样会触发定义

    在基表上的触发器。 ( Oracle 支持在视图上显式的定义触发器和定义一些逻辑约束)

 

使用视图的好处:

    可把复杂的 SQL 语句简单化

    可保证数据的安全性,限制对数据的访问,因为它对表中的一些字段是隐藏的

    可使相同的数据以不同形式出现在不同的视图中

 

视图分类:

    简单视图

       只从一个表中获取数据

       不包含函数

       不包含分组数据

       可通过该视图进行 DML 操作

   

    复杂视图

       从多个表中获取数据

       包含函数

       包含分组数据

       不一定能通过视图进行 DML 操作

   

创建视图:

    CREATE [OR REPLACE] FORCE NOFORCE VIEW view_name [alias [,alias] ... ]

    AS subquery

    [WITH CHECK OPTION]

    [WITH READ ONLY]

 

    OR REPLACE      如果视图存在,重建、修改这个视图

    FORCE          不管引用的表是否存在,都创建这个视图

    NOFORCE         只有当表存在的时候,才能创建这个视图(默认方式)

    WITH CHECK OPTION 只有子查询能够检索出的行才能够被插入 , 修改 , 或删除。默认情况下对此不作检查

                     没有指定约束名,系统会自动为约束命名,形式为 SYS_Cn

    WITH READ ONLY         只读 , 不可对视图做 DML 操作

   

    需要注意的是,在子查询中不能包含 ORDER BY , 子查询可以是复杂的 SELECT 语句

 

 

修改视图

     使用 CREATE OR REPLACE VIEW 子句修改视图

   

删除视图:

    DROP VIEW view_name

 

视图中使用 DML 的规定:

    当视图定义中含有以下元素之一不能使用 INSERT

    组函数

    GROUP BY ORDER BY

    DISTINCT

    ROWNUM

    列的定义为表达式

    表中非空的列,在视图定义中未包括

 

    视图定义含有以下元素不能使用 UPDATE

    组函数

    GROUP BY ORDER BY

    DISTINCT

    ROWNUM

    列的定义为表达式

 

    视图包含以下元素不能 DELETE

    组函数

    GROUP BY ORDER BY

    DISTINCT

    ROWNUM

 

 

与视图有关的数据字典:

    DBA _ VIEWS

    USER_VIEWS

 

-- 演示创建视图  

    SQL > create or replace view vw_emp as

      2   select empno , ename , sal from emp where sal > 2500 ;

 

    View created .

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES             2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

         7902 FORD              3000

 

    SQL > update vw_emp set sal = 3500 where ename = 'FORD' ;   -- 可以更新并且直接修改了基表

 

    1 row updated .

 

    SQL > select * from emp where ename = 'FORD' ;

 

         EMPNO ENAME       JOB               MGR HIREDATE          SAL        COMM      DEPTNO

    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------

         7902 FORD        ANALYST          7566 03 - DEC - 81        3500                     20

 

    SQL > insert into vw_emp select 9999 , 'Robinson' , 6000 from dual ;   -- 可以插入并且直接修改了基表

 

    1 row created .

 

    SQL > select * from emp where empno = 9999 ;                    

 

         EMPNO ENAME       JOB               MGR HIREDATE           SAL        COMM      DEPTNO

    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------

         9999 Robinson                                         6000

     

    1 rows selected .

 

    SQL > delete from emp where ename = 'Robinson' ; -- 可以删除并且直接修改了基表

 

    1 row deleted .

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES             2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

         7902 FORD              3500

 

    SQL > rollback ;

 

    Rollback complete .

 

 

-- 使用 with check option

    -- 使用 WITH CHECK OPTION 子句确保 DML 只能在特定的范围内执行,任何违反

    --WITH CHECK OPTION 约束的请求都会失败

   

    SQL > create or replace view vw_emp                     

      2   as

      3   select empno , ename , sal from emp where sal   > 2500

      4   with check option ;

 

    View created .

 

    SQL > insert into vw_emp select 9999 , 'Robinson' , 2000 from dual ;   -- 不满足条件 sal > 2500 不可插入

    insert into vw_emp select 9999 , 'Robinson' , 2000 from dual

              *

    ERROR at line 1 :

    ORA - 01402 : view WITH CHECK OPTION where - clause violation

 

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES             2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

         7902 FORD              3000

 

    SQL > delete from vw_emp where empno = 7902 ;      -- 满足条件 sal > 2500 可以删除 , 并且修改了基表

 

    1 row deleted .

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES             2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

 

    SQL > select   * from emp ;

 

         EMPNO ENAME       JOB               MGR HIREDATE          SAL        COMM      DEPTNO

    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------

         7369 SMITH       CLERK            7902 17 - DEC - 80         800                     20

         7499 ALLEN       SALESMAN         7698 20 - FEB - 81        1600         300          30

         7521 WARD        SALESMAN         7698 22 - FEB - 81        1250         500          30

         7566 JONES       MANAGER          7839 02 - APR - 81        2975                     20

         7654 MARTIN      SALESMAN         7698 28 - SEP - 81        1250        1400          30

         7698 BLAKE       MANAGER          7839 01 - MAY - 81        2850                     30

         7782 CLARK       MANAGER          7839 09 - JUN - 81        2450                     10

         7788 SCOTT       ANALYST          7566 19 - APR - 87        3000                     20

         7839 KING        PRESIDENT             17 - NOV - 81        5000                     10

         7844 TURNER      SALESMAN         7698 08 - SEP - 81        1500           0          30

         7876 ADAMS       CLERK            7788 23 - MAY - 87        1100                     20

 

         EMPNO ENAME       JOB               MGR HIREDATE          SAL        COMM      DEPTNO

    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------

         7900 JAMES       CLERK            7698 03 - DEC - 81         950                     30

         7934 MILLER      CLERK            7782 23 - JAN - 82        1300                     10

 

    13 rows selected .

 

    SQL > rollback ;

 

    Rollback complete .

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES              2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

         7902 FORD              3000

 

    SQL > update vw_emp set sal = 2000 where empno = 7499 ;    -- 不满足条件 , 不能更新

 

    0 rows updated .

 

--WITH READ ONLY 屏蔽 DML 操作

    -- 可以使用 WITH READ ONLY 选项屏蔽对视图的 DML 操作

    -- 任何 DML 操作都会返回一个 Oracle server 错误

 

    SQL > create or replace view vw_emp

      2   as

      3   select empno , ename , sal from emp where sal > 2500

      4   with read only ;

 

    View created .

 

    SQL > insert into vw_emp select 9901 , 'Robinson' , 3000 from dual ;

    insert into vw_emp select 9901 , 'Robinson' , 3000 from dual

    *

    ERROR at line 1 :

    ORA - 01733 : virtual column not allowed here

 

 

    SQL > select * from vw_emp ;

 

         EMPNO ENAME              SAL

    ---------- ---------- ----------

         7566 JONES             2975

         7698 BLAKE             2850

         7788 SCOTT             3000

         7839 KING              5000

         7902 FORD              3000

 

    SQL > update vw_emp set sal = 8000 where empno = 7902 ;

    update vw_emp set sal = 8000 where empno = 7902

                    *

    ERROR at line 1 :

    ORA - 01733 : virtual column not allowed here

 

 

    SQL > delete from vw_emp where empno = 7566 ;

    delete from vw_emp where empno = 7566

              *

    ERROR at line 1 :

    ORA - 01752 : cannot delete from view without exactly one key - preserved table

     

    -- 创建复杂视图

    SQL > create view vw_sum_emp ( name , minsal , maxsal , avgsal )

      2   as

      3   select dname , min ( e . sal ), max ( e . sal ), avg ( e . sal )

      4   from emp e

      5     join dept d

      6       on e . deptno = d . deptno

      7   group by dname ;

 

    View created .

 

    SQL > select * from vw_sum_emp ;

 

    NAME                MINSAL      MAXSAL      AVGSAL

    -------------- ---------- ---------- ----------

    ACCOUNTING            1300        5000 2916.66667

    RESEARCH               800        3000        2175

    SALES                  950        2850 1566.66667

 

-- 查询与视图有关的数据字典

    SQL > select view_name , text from user_views ;

 

    VIEW_NAME                       TEXT

    ------------------------------ --------------------------------------------------------------------------------

    VW_SUM_EMP                       select dname , min ( e . sal ), max ( e . sal ), avg ( e . sal )

                               from emp e

                                  join dept d

                                   on e . deptno = d . deptno

                               group by dname

 

    VW_EMP                          select empno , ename , sal from emp where sal > 2500

                               with read only

 

更详细的创建视图的语法:

    http :// download . oracle . com / docs / cd / B19306_01 / server .102 / b14200 / statements_8004 . htm#SQLRF01504

   

更多参考:

   

Oracle 数据库实例启动关闭过程

 

Oracle 10g SGA 的自动化管理

 

使用 OEM,SQL*Plus,iSQL*Plus 管理 Oracle 实例

 

Oracle 实例和 Oracle 数据库 (Oracle 体系结构 )

 

SQL 基础 --> 常用函数

 

SQL 基础 --> 过滤和排序

 

SQL 基础 -->SELECT 查询

 

SQL 基础--> 视图(CREATE VIEW)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论