第9章 視圖

target

掌握什么是視圖
掌握視圖的創(chuàng)建
掌握視圖的相關(guān)操作
掌握視圖的修改和刪除

1. 什么是視圖

1.1 認(rèn)識(shí)視圖

根據(jù)官方的文檔可以這樣理解視圖:它是一個(gè)基于一個(gè)表或多個(gè)表的邏輯表,視圖本身不包含任何數(shù)據(jù)。

通俗來說,可以把視圖看成是虛擬的表,只是一個(gè)査詢語句的結(jié)果,它的數(shù)據(jù)最終是從表中獲取的,這些表通常稱為源表或基表。當(dāng)基表的數(shù)據(jù)發(fā)生變化時(shí),視圖里的數(shù)據(jù)同樣發(fā)生變化。通常視圖的數(shù)據(jù)源有下面三種情況:

  • 單一表的子集。
  • 多表操作結(jié)果集。
  • 視圖的子集。

1.2 視圖的作用

  • 使數(shù)據(jù)簡化。

    在表中很多數(shù)據(jù)對(duì)業(yè)務(wù)來說是冗余的,這時(shí)開發(fā)者會(huì)使用比較復(fù)雜的SQL 語句得到自己想要的。實(shí)際開發(fā)中不能要求毎個(gè)人都能做到這一點(diǎn),所以,通常情況下由一個(gè)人把該復(fù)雜語句做成視圖,其他人員直接調(diào)用該視圖即可。這樣對(duì)視圖使用人員就簡化了數(shù)據(jù),隱藏了數(shù)據(jù)的復(fù)雜性。

  • 使數(shù)據(jù)更加獨(dú)立。

    程序開發(fā)時(shí),大多數(shù)是程序直接訪問數(shù)據(jù)庫的表,當(dāng)這些表的結(jié)構(gòu)隨著業(yè)務(wù)的變化而不得不重新設(shè)計(jì)時(shí)會(huì)影響到程序(通常表一旦設(shè)計(jì)完成就很難再做修改),所以可以使得程序直接訪問視圖。這樣視圖就可以把程序和數(shù)據(jù)庫的表隔離開來,降低開發(fā)者的勞動(dòng)成本。

  • 增加安全性。

    視圖可以査詢表指定的列來展現(xiàn)給用戶,而不必讓使用者完全看見表的 、 所有字段。這種情況很多是一個(gè)公司提供給其他合作伙伴査詢數(shù)據(jù)的接口,而視圖通常也會(huì)設(shè)成只讀屬性。

1.3 視創(chuàng)建圖的語法

create [or replace ] [ noforce| force] view
    [schma.]view
    [(alias,...) inline_constraint(s)]
        [out_of_line_constraint(s)]
as subquery
[
  with { read only | check option [CONSTRAINT constraint]]}
];

語法說明:

  • OR REPLACE:表示新建視圖可以覆蓋同名視圖。
  • noforce| force:表示是否強(qiáng)制創(chuàng)建視圖。例如,在基表不存在的情況下就創(chuàng)建視圖是有錯(cuò)誤的,這時(shí)可以用FORCE關(guān)鍵詞強(qiáng)制創(chuàng)建視圖,然后再創(chuàng)建基表。Oracle中NOFORCE是默認(rèn)值。
  • ( schema. |view:這是視圖的所屬方案名稱和視圖本身的名稱。
  • [(alias,...) inline_constraint(s)]:視圖字段的別名和內(nèi)聯(lián)約束。
  • [out_ofJine_constraint(s)]:也是約束,是與inline, constraint(s)相反的聲明方式。
  • WITH READ ONLY:設(shè)置視圖只讀,這樣的視圖具有更高的安全性。
  • WITH CHECK OPTION [ CONSTRAINT constraint ):—旦使用該限制,當(dāng)對(duì)視圖増加或修改數(shù)據(jù)時(shí)必須滿足子?xùn)嗽兊臈l件。也就是說,是把子?xùn)嗽兊臈l件作為一個(gè)約束, 而constraint是這個(gè)約束的名稱。

注意:大括號(hào)是必填語法。

1.4 為用戶授創(chuàng)建視圖權(quán)限

創(chuàng)建視圖需要有Create View系統(tǒng)權(quán)限。

① 查看當(dāng)前用戶具有的權(quán)限:

select * from session_privs;

② 為用戶授權(quán):

授權(quán)需要先登錄系統(tǒng)用戶:

請(qǐng)輸入用戶名:  sys
輸入口令:as sysdba

授權(quán)語句:

grant create view to scott;

2. 視圖的創(chuàng)建

可以直接使用SQL語句創(chuàng)建一個(gè)視圖,也可以使用可視化工具來創(chuàng)建。

創(chuàng)建視圖前先列出表EMP (員工表)和DEPT (部門表)的記 錄,方便和視圖做對(duì)比。

EMP表數(shù)據(jù):

SQL> set linesize 200
SQL> select * from emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-12月-80            800                    20
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10
      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20
      7839 KING       PRESIDENT            17-11月-81           5000                    10
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7902 FORD       ANALYST         7566 03-12月-81           3000                    20
      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10

已選擇14行。

DEPT表數(shù)據(jù):

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

2.1 創(chuàng)建單表視圖

創(chuàng)建視圖展示2行,工作是”CLERK“的數(shù)據(jù):

create or replace view simple_emp_view
as
    select  EMPNO,ENAME,JOB,SAL,DEPTNO
    from emp
    where job = 'CLERK'
    and rownum < 3;

使用rownum來限制行數(shù)。

查看創(chuàng)建成功的視圖:

SQL> select * from simple_emp_view;

     EMPNO ENAME      JOB              SAL     DEPTNO
---------- ---------- --------- ---------- ----------
      7369 SMITH      CLERK            800         20
      7876 ADAMS      CLERK           1100         20

2.2 創(chuàng)建多表視圖

??:查詢出工作是”CLERK“,并且部門在”NEW YORK“的員工信息

create or replace view multi_emp_view as    
  select e.ename,e.job,e.sal,d.loc  
  from emp e,dept d     
  where e.deptno = d.deptno and e.job='CLERK' and d.loc='NEW YORK';

2.3 創(chuàng)建基于視圖的視圖

前面創(chuàng)建的視圖是基于表的,還可以創(chuàng)建基于視圖的視圖。很少使用。

??:

create or replace view vi_emp_view as   
  select ename,job,loc from multi_emp_view ;

2.4 創(chuàng)建沒有源表的視圖

在數(shù)據(jù)庫開發(fā)過程中,如果設(shè)計(jì)工作做得很好,就可能出現(xiàn)在沒有源表時(shí)先把視圖創(chuàng)建出來的情況。因?yàn)楦鶕?jù)設(shè)計(jì),基表是肯定要建的。

create or replace view notable_emp_view as  
  select ename,job,sal from notable;

輸出:

第 3 行出現(xiàn)錯(cuò)誤:ORA-00942: 表或視圖不存在

這里說明視圖創(chuàng)建不成功。使用force關(guān)鍵字可以避免這種情況。該關(guān)鍵字表示創(chuàng)建視圖時(shí),無視源表是否存在。

create or replace force view notable_emp_view as    
  select ename,job,sal from notable;

輸出:

警告: 創(chuàng)建的視圖帶有編譯錯(cuò)誤。

說明視圖創(chuàng)建成功。

3. 查看視圖

可以利用下面的語句查看當(dāng)前用戶下的所有視圖:

select view_name from user_views;

在SQL plus中,當(dāng)查詢出來的列寬不夠時(shí)可以使用下面的語句改變字段寬度:

col 列 format A15

查看視圖的創(chuàng)建語法:

select text from all_views where view_name = '視圖名';

注意:視圖名要全部大寫。

4. 操作視圖數(shù)據(jù)的限制

視圖增加或更新數(shù)據(jù)實(shí)際上是在操作視圖的源表。

除此之外,視圖本身可以設(shè)置更新限制條件。

4.1 視圖read only設(shè)置

創(chuàng)建視圖時(shí),為了避免用戶修改數(shù)據(jù),可以把視圖設(shè)成只讀屬性。

create or replace view sim_emp_view as  
  select ename,job,sal from emp where job='CLERK'   
  with read only;

當(dāng)插入或者修改視圖數(shù)據(jù)時(shí),會(huì)提示”無法對(duì)只讀視圖執(zhí)行DML操作“;

4.2 視圖check option設(shè)置

在某些情況下允許修改視圖的數(shù)據(jù),修改數(shù)據(jù)的本質(zhì)是修改視圖源表的數(shù)據(jù)。

假如某個(gè)視圖査詢岀來的是年齡大于20的所有數(shù)據(jù),如果為該視圖增加一條年齡為10的記錄,那么該記錄將不會(huì)出現(xiàn)在視圖中。顯然這是不符合邏輯的。為了避免這種情況的發(fā)生,可以利用 CHECK OPTION選項(xiàng)來設(shè)置視圖的檢査約束。
CHECK OPTION選項(xiàng)表示視圖啟動(dòng)了和子?xùn)嗽儣l件一樣的約束。也就是說,如果對(duì)視圖修改或插入的數(shù)據(jù)和査詢條件不一致,那么該操作會(huì)被中止。

先創(chuàng)建一個(gè)emp_temp表:

create table emp_temp as select * from emp;

創(chuàng)建視圖:

create or replace view simple_emp_view as   
  select ename,job,sal 
  from emp_temp 
  where job='CLERK' 
  with check option;

這時(shí)如果要增加或修改數(shù)據(jù),就要符合where后面的條件,即工作是”CLERK“。

為了驗(yàn)證視圖的check option設(shè)置是否生效,對(duì)視圖進(jìn)行MDL操作。

① 增加數(shù)據(jù)

insert into simple_emp_view(ename,job,sal)
values ('aa','SALESMAN',10000);

由于增加的數(shù)據(jù)job字段不是”CLERK“,會(huì)報(bào)錯(cuò):

第 1 行出現(xiàn)錯(cuò)誤:ORA-01402: 視圖 WITH CHECK OPTION where 子句違規(guī)

② 修改數(shù)據(jù)

update simple_emp_viewset job='SALESMAN'
where ename='SMITH';

會(huì)報(bào)錯(cuò):

第 1 行出現(xiàn)錯(cuò)誤:ORA-01402: 視圖 WITH CHECK OPTION where 子句違規(guī)

③ 刪除數(shù)據(jù)

delete from simple_emp_view
where job = 'SALESMAN';

輸出:

已刪除0行。

說明刪除沒起作用。

5. 視圖的修改

視圖的修改比較特殊,不能像表一樣修改,更準(zhǔn)確地說它沒有修改選項(xiàng),可以覆蓋原有視圖,但這不會(huì)影響視圖的使用。因?yàn)橐晥D本身不包含數(shù)據(jù),所以覆蓋原視圖時(shí)就不存在數(shù)據(jù)丟失的問題了。

6. 視圖的刪除

視圖的刪除和表的刪除一樣。

語法:

drop view [schema.]view [cascade constraints];

說明:

cascade constraints:刪除視圖時(shí)刪除約束。

??:刪除simple_emp_view視圖

drop view simple_emp_view;

7. 案例

下面是4張表,是簡單的二手車買賣的原型。

(1) 買賣記錄表(tradrec)

字段名 注釋 數(shù)據(jù)類型
id 序號(hào) varchar2(10)
carrgnum 車牌號(hào) varchar2(8)
carbrandid 商標(biāo)編號(hào) varchar2(8)
bgdate 交易日期 date
bargainer 交易者 varchar2(10)
remark 備注 varchar2(200)

建表語句:

create table tradrec(   
  id varchar2(10) primary key,  
  carrgnum varchar2(8),  
  carbrandid varchar2(8),  
  bgdate date,  
  bargainer varchar2(10),  
  remark varchar2(200)
);

(2) 汽車品牌表(carbrandtab)

字段名 注釋 數(shù)據(jù)類型
carbrandid 品牌編碼 varchar(8)
carbrand 汽車品牌名稱 varchar(20)

建表語句:

create table carbrandtab(   
  carbrandid varchar(8) primary key,  
  carbrand varchar(20)
);

(3) 車輛車色表(carfettletab)

字段名 注釋 數(shù)據(jù)類型
carfettleid 成色編碼 varchar(2)
carfettle 成色 varchar(20)
create table carfettletab(  
  carfettleid varchar(2) primary key,  
  carfettle varchar(20)
);

(4) 二手車記錄表(carinfo)

字段名 注釋 數(shù)據(jù)類型
carid 編號(hào) varchar2(10)
carrgnum 車牌號(hào) varchar2(8)
carbrandid 品牌編號(hào) varchar2(8)
carfettleid 成色編碼 varchar2(2)
flag 是否手售出 varchar2(1)

建表語句:

create table carinfo(   
  carid varchar2(10),  
  carrgnum varchar2(8),  
  carbrandid varchar2(8),  
  carfettleid varchar2(2),  
  flag varchar2(1),  
  primary key(carid),  
  constraint  fk_carinfo_carbrand foreign key(carbrandid) 
  references carbrandtab(carbrandid) on delete cascade,  
  constraint fk_carinfo_carfettletab foreign key(carfettleid) 
  references carfettletab(carfettleid) on delete cascade
);

要求:

??:列出售出車輛的明細(xì)列表,包括序號(hào)、車牌號(hào)、車品牌、售出日期、售出人、成色

create or replace view tradrec_detail_view as   
  select tc.id,tc.carrgnum,cb.carbrand,tc.bgdate,tc.bargainer,cfb.carfettle 
  from tradrec tc,carinfo co,carbrandtab cb,carfettletab cfb    
  where tc.carbrandid = cb.carbrandid   
  and co.carfettleid = cfb.carfettleid  
  and tc.carrgnum = co.carrgnum 
  order by cb.carbrand;

??:統(tǒng)計(jì)某個(gè)日期之后不同品牌的車主賣出的數(shù)量

create or replace view tradrec_stat_view as 
  select cb.carbrand,count(carrgnum) as quantity    
  from tradrec tc,carbrandtab cb    
  where tc.bgdate > to_date('2020-5-1','YYYY-MM-DD')    
  and tc.carbrandid = cb.carbrandid 
  group by cb.carbrand;

習(xí)題

一、選擇題

  1. 下面有關(guān)視圖的數(shù)據(jù)來源.敘述不正確的是( ).
    A.視圖數(shù)據(jù)是用戶直接添加到視圖中的
    B.視圖數(shù)據(jù)來源于單表
    C.視圖數(shù)據(jù)來源于多表
    D.視圖數(shù)據(jù)來源于其他視圖

  2. 創(chuàng)建視圖帶SUM函數(shù),視圖數(shù)據(jù)是否可以更新?( )

    A.不可以
    B.可以

  3. 視圖中CHECK OPTION設(shè)置有什么作用?( )
    A.沒有實(shí)際作用
    B.檢査視圖更新數(shù)據(jù)是否符合視圖創(chuàng)建時(shí)的査詢條件
    C.檢査數(shù)據(jù)是否有更新
    D.不允許向基表中更新數(shù)據(jù)
    二、簡答題

    1. 視圖的約束是否和表的約束一樣?
    2. 當(dāng)對(duì)視圖做刪除數(shù)據(jù)操作時(shí),如果視圖里沒有符合條件的數(shù)據(jù),但基表存在符合條件的 數(shù)據(jù),實(shí)際會(huì)出現(xiàn)什么情況?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容