1. 程式人生 > >檢視和觸發器部分

檢視和觸發器部分

1.  檢視定義:檢視是從一個或幾個基本表(或檢視)匯出的表,它與基本表不同,是一個虛表,資料庫中只存放檢視的定義。一旦基本表的資料發生變化,從檢視中查詢也會變換。

   1. 建立檢視

create view <檢視名>[(列名)[,<列名>...)]
as <子查詢>
[with check option]

   其中子查詢可以是任意的 select 語句是否能有order by 字句和distinct 短句取決於具體的系統。

   with check option 表示對於檢視進行update,insert,delete的時候要保證更新,插入,刪除的行為滿足檢視定義中的謂詞條件(即子查詢中的條件表示式)

   組成檢視的屬性列名或者全部省略或者全部指定。如果省略檢視的各個屬性列名,則隱含該檢視由子查詢中select 字句目標列中的諸欄位組。但是出現以下情況是必須明確指定

   (1)某個目標列不是單純的屬性名,而是聚集函式或者列表達式

   (2)多表連線的時候選出了幾個同名列作為檢視的欄位

   (3)需要在檢視中為某個列啟用新的更合適的名字

   給個例子看下:(就這是最基本的檢視的建立)

create view V_view1_J122
as
select * from T_stud_J122
where 'U'||sno=user or 'U'||mno=user or
'U'||majorno=user;

   下面就是多表連線,需要指定的那種

create view is_si(sno,sname,grage)
as
select Student.sno,sname,grade
from Student,SC
where Sdep="is" and Student.sno=SC.sno 
and SC.cno="1";

   2. 查詢檢視

   建立了檢視就可以像基本表一樣進行查詢

   但是在不同使用者查詢對應的檢視的時候要加上你建立檢視的使用者

select * from U_J122.V_view1_J122;

   3. 更新檢視

   更新檢視是是指通過檢視來插入,刪除和修改資料,但是由於檢視是虛表,所以檢視的更新實質上還是對於基本表的更新,但是不建議用檢視去更新資料。

   要修改的話最好加上with check option 這樣的話在通過檢視更新資料的時候,不會更新掉不屬於該檢視範圍的資料。

   注意:並不是所有的檢視都是可更新的。

   因為通過檢視的更新語句最後還是要轉換為對於基本表更新的語句,但是有時候檢視的更新不能唯一的有意義的轉換成對應基本表的更新。

   注意不允許更新和不可更新是有區別的。

   不允許更新的七種情況:

    1. 若檢視是由兩個以上基本表匯出的,則此檢視不允許更新。

    2. 若檢視的欄位來自欄位表示式或常數,則不允許對此檢視執行INSERT和UPDATE操作,但允許執行DELETE操作。

    3. 若檢視的欄位來自集函式,則此檢視不允許更新。

    4. 若檢視定義中含有GROUP BY子句,則此檢視不允許更新。

    5. 若檢視定義中含有DISTINCT短語,則此檢視不允許更新。

    6. 若檢視定義中有巢狀查詢,並且內層查詢的FROM子句中涉及的表也是匯出該檢視的基本表,則此檢視不允許更新。例如將成績在平均成績之上的元組定義成一個檢視GOOD_SC: CREATE VIEW     GOOD_SC AS SELECT Sno, Cno, Grade FROM SC WHERE Grade> (SELECT AVG(Grade) FROM SC);   匯出檢視GOOD_SC的基本表是SC,內層查詢中涉及的表也是SC,

    所以檢視GOOD_SC是不允許更新的。

    7. 一個不允許更新的檢視上定義的檢視也不允許更新。

   4. 檢視的作用

    1.檢視能夠簡化使用者的操作

    2.檢視使使用者能以多種角度看待同一資料

    3.檢視對重構資料庫提供一定程度的邏輯獨立性‘   

    4.檢視能夠對機密資料提供安全保護

    5.適當利用檢視可以更清晰地表達查詢

2.  觸發器

    1. 觸發器是使用者定義在關係表上的一類由事件驅動的特殊過程(事情—條件—動作規則)。一旦定義,觸發器會儲存在資料庫的伺服器中,任何使用者對於表的增刪改操作都會自動觸發相應的觸發器。

    2. 定義觸發器

create trigger <觸發器名>
{before | after}<觸發事件> on <表名> /*指明觸發器啟用的時間是執行觸發事件前後*/
 
referencing new | old row as <變數> /*指出引用的變數*/
for each {row | statement} /*定義觸發器的型別,指明動作體執行的頻率*/
[when <觸發條件>]<觸發動作體>

     例項:

create trigger tg_T_attend_J122
    before insert or update or delete on T_attend_J122
    for each row
declare
    mnewscore binary_integer;
    moldscore binary_integer;
begin 
    if inserting then
        select score into mnewscore from T_attendscore_J122 where mstatus=:new.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)+mnewscore where T_stud_J122.sno=:new.sno;
    elsif updating then
        select score into mnewscore from T_attendscore_J122 where mstatus=:new.mstatus;
        select score into moldscore from T_attendscore_J122 where mstatus=:old.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)-moldscore where T_stud_J122.sno=:old.sno;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)+mnewscore where T_stud_J122.sno=:new.sno;
    else 
        select score into moldscore from T_attendscore_J122 where mstatus=:old.mstatus;
        update T_stud_J122 set sum_evaluation=nvl(sum_evaluation,0)-moldscore where T_stud_J122.sno=:old.sno;
    end if;
end;

     3. 觸發器的執行

      觸發器的執行由觸發事件執行,如果一個表上定義了多個觸發器。執行順序是先執行表上的before觸發器,啟用觸發器的sql語句,再執行表上的after觸發器。  

      對於同一個表的多個before , after 觸發器按建立的順序來進行。

    4. 刪除觸發器

dalete trigger <觸發器名> on <表名>