数据库讲义 __ 【建立和使用视图】

实验22:建立和使用视图

  1. 【View视图】

使用视图为了我们的方便,增加了数据库的负担,视图下降数据库的性能,视图是查询语句的别名,视图的定义存在于数据字典中

  1. 【User_Views 查看视图的定义】

视图是好东西,用好了提高开发的效率和安全性,反之数据库的性能极大的下降,数据库是给明白人用的。物有所长,必有所短,万物一理,视图也不例外。Oracle 的所有字典都是视图。极大的提高了管理性,极大的提高了可使用性,我们学习 oracle,就要跟 oracle 学习,他怎么玩,我们就怎么玩,肯定可以成为数据库大师

  1. 【使用视图的目的】

1、限制对数据库的访问

2、将复杂的查询包起来,化繁为简

3、提供给用户独立的数据

4、在同一个表上建立不同的视图,减少基表的个数。

5、普通得视图下降数据库的性能,不能起到优化的目的,所以在使用视图关联查询的              时候一定要注意,可能使我们的系统性能隐含着巨大的隐患。我见到一个应用,表          面就 3 行的语句,客户说运行慢,一看执行计划,1 米多长,为什么,使用了视              图。表面简单,实际是个很复杂的查询。

4、 【建立、使用视图】

如果没有权限,请先授权。在 10G 以前 Scott 用户是有 Create view 的权限的,10g        以后就没有了,因为默认的角色的权限发生了变化。

SQL >  Create  view  v1  as  select  deptno, min( sal )  salary

 from  emp  group  by  deptno;

SQL >  Desc v1;

    Name                                         Null?                                                 Type   

deptno                                                                                               NUMBER(2)

salary                                                                                                 NUMBER

其中 salary 是 min(sal)的别名,因为函数不能作为列的名称,列的别名的本质用法,将非法的合法化。

SQL >  Select * from v1;

   deptno                  salary

     30                       950

     20                       800

     10                      1300

视图 v1 只是一个定义,没有独立的数据,数据还是存放在 emp 表中。

SQL >  Select VIEW_NAME, text from user_views 查看视图的定义

     View_name                                                                                   text                             

            V1                                               select deptno,min(sal) salary from emp group by deptno

  1. 【视图的使用】

1、你使用视图的时候可以把视图当做表。

2、数据库在解释查询语句的时候会查找视图的定义。

3、每次普通视图查询的时候都要进行基表数据的查找。

4、视图中不存放数据,除了物化视图,物化视图是快照,真正的存放数据,需要刷新。

6、【视图的执行过程】

SQL >  Select  *  from  v1;

查找 user_views 取出 v1 视图的定义。

select  deptno, min( sal )  salary  from  emp  group  by  deptno;

【点评】:数据库执行查找到的定义

所以说视图下降数据库的性能,尤其在复杂的视图相互关联查询的时候,你觉得语法很简单,其实视图内调用了大量的表,容易使我们麻痹大意

  1. 【修改视图】

SQL >  Create  or  replace  view  v1  as  select  *  from  dept;

【点评】:就是将视图的定义替换。

  1. 【删除视图】

SQL >  Drop  view  v1;

【点评】:在数据字典中将视图的定义清除,不能影响基本表中的数据

  1. 【视图上运行DML】

简单的视图可以运行 dml ,等于直接操作基本表的数据,但受到一些限制。

9.1、【Delete的限制】

1、有组函数

2、有 group by 子句

3、用了 distinct 关键字

4、有 rownum 列

Delete v1 where deptno=10;

ORA-01732: 此视图的数据操纵操作非法

9.2、【Update的限制】

1、有组函数

2、有 group by 子句

3、用了 distinct 关键字

4、有 rownum 列

5、有表达式的列

 

 

9.3、【Insert的限制】

1、有组函数

2、有 group by 子句

3、用了 distinct 关键字

4、有 rownum 列

5、有表达式的列

6、基本表中有 not null 的列,但该列没有出现在视图的定义里

10、【With Check Option选项】

SQL >  Create  or  replace  view  empvu20  as  select  *  from  emp

     where  deptno = 20  with  check  option  constraint  empvu20_ck

建立视图的时候带有检测约束,约束就是 where 的条件。确保在 update 视图的时候,视图所选择的行不会发生变化,是对视图中数据的一种保障。

Update  empvu20  set  deptno=10;

【ORA-01402】:视图 with  check  option  where 子句违规

  1. 【Read  Only 选项】

SQL >  Create or replace  view  empvu10 (employee_number,  employee_name,  job_title)  As  select  empno,  ename, job from emp where deptno = 10 with read only;

禁止 dml 操作视图

  1. 【Inline内嵌式视图】:将 from 子句中的子查询起别名

SQL >  select  ename, sal  from  emp,

(select  deptno, avg( sal )  salary  from  emp  group  by  deptno)  a

where  emp.deptno = a.deptno  and  emp.sal > a.salary;

【解释】:a 就是内嵌式视图,当前语句内起作用,一次性的,在语句外不可引用。

13、【Top-n 查询】:查询工资前三名

SQL >  Select  rownum  as  renk, ename, sal  deom

 (select  ename, sal  from  emp  order by  sal  desc) where  rownum  <= 3

【解释】:From 子句后为视图,内

  1. 【rownum 伪列】

按照取出数据的顺序显示,我们使用了 rownum 伪列。表 EMP 中并没有 ROWNUM 列,这是数据库计算出来的,按照数据库取出的顺序来决定顺序是几,所以一定要使用小于等于,而不能使用大于等于

【【  知识点总结  】】

1、掌握视图的原理

2、建立简单的视图

3、在视图上进行 dml

4、内嵌式视图

5、查看视图的定义

6、删除视图

 

 

 

实验23:查询结果的集合操作

【【  集合操作包括  】】

1、并集 union /union all

2、交集 intersect

3、补集 minus

1、【建立实验表】

drop  table  t2  purge;

drop  table  t1  purge;

 

Create  table  t1  as  select  deptno, ename, sal  from  emp 

Where  deptno  in ( 10, 20 )  order  by  deptno;

Create  table  t2  as  select  deptno, ename, sal  from  emp

Where  deptno  in ( 20, 30 )  order  by  deptno;

 

SQL >  select  *  from  t1;

       Deptno            ename                 sal                         

         10                 CLARK               2450

         10                 KING                  5000

         10                 MILLER              1300

         20                 FORD                 3000

        20                 JONES                2975

       20                 SMITH                  800

 

SQL >  select  *  from  t1;

       Deptno            ename                 sal                          

          20                 FORD                  3000

          20                 JONES                 2975

          20                 SMITH               800

          30                 TURNER             1500

          30                 JAMES               950

          30                 BLAKE                     2850

          30                 WARD                 1250

          30                 ALLEN               1600

         30                 MARTIN               1250

这两张表中既有相同部分又有不同部分

 

2、【Union All】

SQL >  select  *  from  t1  union all  select  *  from  t2;

       Deptno            ename                        sal                         

         10                  CLARK                     2450

         10                 KING                         5000

         10                 MILLER                     1300

         20                 FORD                         3000

         20                 JONES                        2975

         20                 SMITH                          800

         20                 FORD                         3000

         20                 JONES                        2975

         20                 SMITH                          800

         30                 TURNER                     1500

         30                 JAMES                         950

         30                 BLAKE                         2850

         30                 WARD                          1250

         30                 ALLEN                        1600

        30                 MARTIN                       1250

注释:将 t1 和 t2 的结果一起显示。Union  All不排序操作也不去掉重复的行

  1. 【Union】

SQL >  select  *  from  t1  union  select  *  from  t2;

       Deptno            ename                        sal                         

         10                 CLARK                      2450

         10                 KING                         5000

         10                 MILLER                    1300

         20                 FORD                       3000

         20                 JONES                     2975

        20                 SMITH                       800

        30                 ALLEN                      1600

        30                 BLAKE                      2850

        30                 JAMES                       950

       30                 MARTIN                     1250

       30                 TURNER                    1500

       30                 WARD                        1250

注释:将 t1 和 t2 的结果一起显示。Union含有排序操作也去掉重复的行。

  1. 【Intersect】

SQL >  select  *  from  t1  intersect  select  *  from  t2;

       Deptno            ename                        sal                         

          20                 FORD                         3000

          20                 JONES                       2975

          20                 SMITH                        800

注释:将 t1 和 t2 的结果的共有部分显示。Intersect含有排序操作也去掉重复的行

 

 

  1. 【Minus】

SQL > select  *  from  t1  minus  select  *  from  t2;

       Deptno            ename                        sal                         

        10                 CLARK                      2450

        10                 KING                         5000

        10                 MILLER                    1300

注释:t1 表有,而且 t2 表没有的行显示出来,去掉重复的行

【【  总结  】】

      在 10g 以前,去掉重复行的操作是使用排序,10g 以后使用 hash 算法,避免了排序。提高了性能,所以结果集是无序的,如果需要有序,使用 order by 语句。10g 以前结果是有序的。

实验24:高级分组RollupCube的用法

【解释】:比普通分组在 Union 要高效,一次扫描干多样的事情,搂草打兔子,一次全部完成了,

  1. 【Rollup】分组

按部门分组 SQL >  select  deptno, sum ( sal )  from  emp  group  by  deptno;

                  Deptno        sum(sal)                

                    30                 9400

                    20                 6775

                    10                 8750

按部门分组求和 SQL > select  deptno, sum(sal)  from  emp  group by rollup(deptno);

                  Deptno        sum(sal)                

                    30                 9400

                    20                 6775

                   10                 8750

   24925

Rollup 分组,一次全表扫描

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

select  deptno, sum ( sal )  from  emp  group  by  rollup ( deptno ) ;

上面这条SQL可以分解为:

SQL >  Select  deptno , sum ( sal )  from  emp  group  by  deptno  union  all

Select  null , sum ( sal )  from  emp  order  by  1 ;

但是两次扫描表,效率很低

 

【【  总结  】】

Group  by  Rollup ( a, b, c, d.......)

的结果集为,共 n+1 个集

Group  by  a, b, c, d  Union all

Group  by  a, b, c  Union all

Group  by  a, b  Union all

Group  by  a  Union all

Group  by  null;

 

【【  根据总结举例子  】】

SQL >  select  deptno, job, sum ( sal )  from  emp  group  by  rollup ( deptno, job );

                  Deptno        job                       sum(sal)          

                      10          CLERK               1300

                      10          MANAGER          2450

                      10          PRESIDENT        5000

10                                      8750

20          CLERK                800

20          ANALYST           3000

20          MANAGER          2975

20                                      6775

30          CLERK               950

30          MANAGER          2850

30          SALESMAN              5600

30                                      9400

24925

结果为:

SQL >  Select  deptno, job, sum ( sal )  from  emp  group  by  deptno, job

union all

select  deptno, null, sum ( sal )  from  emp  group  by  deptno

union all

Select  null, null, sum ( sal )  from  emp;

  1. 【Grouping】

Grouping(列名称)的使用,为了表达该列是否参加了分组活动。 0 为该列参加了分组,1 为该列未参加分组操作

SQL >  Select  deptno , job , grouping ( deptno ), grouping ( job ) ,sum ( sal )

from  emp  group  by  rollup ( deptno , job ) ;

        Deptno  job         grouping(deptno)       grouping(job)               sun(sal)            

10          CLERK               0                         0                  1300

10          MANAGER          0                         0                  2450

10          PRESIDENT        0                         0                  5000

10                                      0                         1                  8750

20          CLERK               0                          0                  800

20          ANALYST           0                          0                  3000

20          MANAGER          0                         0                  2975

20                                      0                         1                  6775

30          CLERK                0                         0                  950

30          MANAGER          0                         0                  2850

30          SALESMAN        0                         0                  5600

30                                      0                         1                  9400

1                         1                  24925

 

 

 

  1. 【Cube分组】

SQL >  Select  deptno ,job ,grouping ( deptno ),

Grouping ( job ) , sum ( sal )  from  emp  group  by  cube ( deptno, job );

结果集拆分为 2**n 个结果集

SQL >  select  deptno ,job ,sum ( sal )  from  emp  group  by  deptno ,job

union all

select  deptno ,null ,sum ( sal )  from  emp  group  by  deptno

union all

select  null ,job ,sum ( sal )  from  emp  group  by  job

union all

Select  null , null , sum ( sal ) from  emp;

实验25:树结构的查询start with 语句

【注释】:实现高级的查询需要,减少了编程序! 层次结构的数据查询

SQL>  select  empno, ename, mgr  from  emp  start  with  ( ename = 'SMITH' )

Connect  by  prior  mgr = empno;

           empno          ename            mgr      

7369             SMITH               7902

7902              FORD               7566

7566             JONES                 7839

7839              KING

  1. 【伪列level】

SQL > select  level, empno,  ename, mgr  from  emp  start  with  (ename = 'SMITH')

Connect  by  prior  mgr = empno;

     level     empno            ename            mgr      

  1           7369                 SMITH               7902

  2           7902               FORD                  7566

  3           7566                 JONES                 7839

        4           7839               KING

  1. 【从树根开始查询】

SQL > select  level, empno,  ename, mgr  from  emp  start  with  (ename = 'KING')

Connect  by  prior  empno = mgr;

     level     empno            ename            mgr      

                1           7839             KING  

2           7566             JONES                 7839

3           7902             FORD                  7566

4           7369             SMITH               7902

2           7698             BLAKE               7839

3           7499             ALLEN               7698

3           7521             WARD                 7698

3           7654             MARTIN              7698

3           7844             TURNER             7698

3           7900             JAMES               7698

    2           7782             CLARK               7839

 

 

  1. 【美化层次的关系】

SQL>  select  lpad ('-', level, '-') || ename  from  emp  start  with  ( ename = 'KING' )

Connect  by  prior  empno = mgr;

               lpad ('-', level, '-') || ename   

-KING

--JONES

---FORD

----SMITH

--BLAKE

---ALLEN

---WARD

---MARTIN

---TURNER

---JAMES

--CLARK

---MILLER

  1. 【删除节点、下级保留】

SQL>  select  level, empno, ename, mgr  from  emp  where  ename <> 'BLAKE'

start  with  ( ename = 'KING' )  connect  by  prior  empno = mgr;

           BLAKE 一个人删除,不影响他的下属

  1. 【删除枝干】

SQL>  select  level, empno, ename, mgr  from  emp  start  with  ( ename = 'KING')

   connect  by  prior  empno = mgr  and  ename < > 'BLAKE' ;

BLAKE 和他的整个部门

实验26:高级DML操作    insert的进一步学习

1、【建立实验表】

SQL>  Drop  table  e1  purge;

Drop  table  e2  purge;

create  table  e1  as  select  ename, sal, hiredate  from  emp  where 9 = 0;

create  table  e2  as  select  ename, sal, hiredate  from  emp  where 9 = 0;

2、【Insert  All】

SQL>  insert  all  

into  e1  values ( ename, sal, hiredate ) 

into  e2  values (ename, deptno, mgr)

selec t  ename, sal, hiredate, deptno, mgr  from  emp  where  deptno = 10;

select  *  from  e1 ;  --查询e1表                select  *  from  e2 ;  --查询e2表

【注释】:All 的含义为:emp 表中的一行将插入到 e1,e2 中

  1. 【Insert  First】

SQL>  insert  first

when  sal > 3000  then  into  e1  values ( ename, sal, hiredate )

when  sal > 2000  then  into  e2  values ( ename, deptno, mgr )

Select  ename, sal, hiredate, deptno, mgr  from  emp ;

【注释】:First 的含义为:一行只能给一张表,即使两个表的条件都符合

实验27:高级子查询

普通的子查询是先运行子查询,再运行外面的查询。有的时候我们需要把外部的查询结果先传入到内部,再运行子查询,子查询的结果再来判断外部的查询。

 

*-*-*-*-*-*-*-*-*-*-*  举个例子  *-*-*-*-*-*-*-*-*

查询哪些员工的工资高于本部门的平均工资

1、【第一种】:

SQL>  select  a.deptno, ename, sal  from  emp  a, (select  deptno , avg(sal) asal

from  emp  group  by  deptno )  b

where  a.deptno = b.deptno  and  a.sal > b.asal  order  by  1;

【执行结果】:

         deptno                       ename                       sal           

10                        KING                          5000

20                        JONES                        2975

20                        FORD                         3000

30                        ALLEN                      1600

30                        BLAKE                            2850

【解释SQL】:

其中 b 为内嵌式视图,asal 为表达式的别名,因为表达式不能做列的名称。别名的含义在于非法的列名合法化。

  1. 【第二种】:

SQL>  select  deptno, ename, sal  from  emp  a

             where  a.sal > (select  avg (sal)  from  emp  where  deptno = a.deptno)

             order by 1;

【执行结果】:

         deptno                       ename                       sal           

10                        KING                          5000

20                        JONES                        2975

20                        FORD                         3000

30                        ALLEN                      1600

30                        BLAKE                      2850

【解释SQL】:

以上两种SQL,第一个为内嵌式的视图,第二个为互动的子查询,两句话的结果完全相同,但内部运行的模式不同

上一篇:oracle实战(一)


下一篇:ubuntu新建用户并允许SSH登录