久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    ORACLE PL/SQL 觸發(fā)器(trigger)學(xué)習(xí)筆記(1)

     艾雪溪 2009-12-11

    1、觸發(fā)器的概念

    觸發(fā)器也是一種帶名的PL/SQL塊。觸發(fā)器類似于過程和函數(shù),因?yàn)樗鼈兌际菗碛新暶鳌?zhí)行和異常處理過程的帶名PL/SQL塊。與包類似,觸發(fā)器必須存儲(chǔ)在數(shù)據(jù)庫(kù)中并且不能被塊進(jìn)行本地化聲明。

    對(duì)于觸發(fā)器而言,當(dāng)觸發(fā)事件發(fā)生的時(shí)候就會(huì)顯式地執(zhí)行該觸發(fā)器,并且觸發(fā)器不接受參數(shù)。

     

    創(chuàng)建觸發(fā)器的語(yǔ)法如下

     


    view plaincopy to clipboardprint?
    CREATE [OR REPLACE] TRIGGER trigger_name  

    {BEFORE | AFTER | INSTEAD OF} triggering_event  

    [referencing_clause]  

    [WHEN trigger_condition]  

    [FOR EACH ROW]  

    Trigger_body;
    CREATE [OR REPLACE] TRIGGER trigger_name

    {BEFORE | AFTER | INSTEAD OF} triggering_event

    [referencing_clause]

    [WHEN trigger_condition]

    [FOR EACH ROW]

    Trigger_body;

    其中referencing_clause子句的用途是通過一個(gè)不同的名稱,引用當(dāng)前正在被更新的記錄行中的數(shù)據(jù)。WHEN子句中的trigger_condition—如果出現(xiàn)—就應(yīng)該首先執(zhí)行判斷,只有當(dāng)這個(gè)條件值為真的時(shí)候,才會(huì)執(zhí)行觸發(fā)器的主體代碼。

     

     

    2、DML觸發(fā)器的激活順序

    1)執(zhí)行before語(yǔ)句級(jí)觸發(fā)器—如果存在這種觸發(fā)器

    2)對(duì)受該語(yǔ)句影響的每一行記錄

    執(zhí)行before行級(jí)觸發(fā)器—如果存在這種觸發(fā)器

    執(zhí)行該語(yǔ)句本身

    執(zhí)行after行級(jí)觸發(fā)器--如果存在這種觸發(fā)器

    3)執(zhí)行after語(yǔ)句級(jí)觸發(fā)器--如果存在這種觸發(fā)器

     

    同一種類型的觸發(fā)器的點(diǎn)火次序沒有經(jīng)過定義。如果該次序很重要的話,那么建議將所有這些操作組合到一個(gè)觸發(fā)器當(dāng)中。

     

    3、行級(jí)觸發(fā)器中的關(guān)聯(lián)標(biāo)識(shí)符

    觸發(fā)器的激活語(yǔ)句每處理一行數(shù)據(jù),行級(jí)觸發(fā)器就會(huì)激活一次。可以在這種行級(jí)觸發(fā)器內(nèi)部,訪問正被處理的記錄行中的數(shù)據(jù)。這是通過兩個(gè)關(guān)聯(lián)標(biāo)識(shí)符--:old和:new—實(shí)現(xiàn)的。關(guān)聯(lián)標(biāo)識(shí)符也是PL/SQL的一種特殊的綁定變量。標(biāo)識(shí)符前面的冒號(hào),既說明這二者都是綁定變量,同時(shí)也說明它們不是一般的PL/SQL變量。PL/SQL編譯器會(huì)將它們看作下面這個(gè)類型的記錄:

     

    Triggering_table%ROWTYPE

     

    其中triggering_table是在其上定義觸發(fā)器的表名。于是,下面這種引用

     

    :new.field

     

    就只有當(dāng)其中的field是該觸發(fā)表中的字段名時(shí)才會(huì)有效。

     

    觸發(fā)語(yǔ)句
    :old
    :new

    INSERT
    未定義—所有字段均為NULL
    觸發(fā)語(yǔ)句完成的時(shí)候,要插入的值

    UPDATE
    更新以前相應(yīng)記錄行的原始值
    觸發(fā)語(yǔ)句完成的時(shí)候,要更新的值

    DELETE
    刪除以前相應(yīng)記錄行的原始值
    未定義—所有字段均為NULL

     

    注意:INSERT語(yǔ)句上沒有定義:old標(biāo)識(shí)符,DELETE語(yǔ)句上也沒有定義:new標(biāo)識(shí)符。如果再INSERT語(yǔ)句上使用:old標(biāo)識(shí)符,或者在DELETE語(yǔ)句上使用:new標(biāo)識(shí)符,PL/SQL并不會(huì)產(chǎn)生錯(cuò)誤,但是這兩個(gè)字段值都會(huì)為NULL。

     

    偽記錄

    雖然在語(yǔ)法構(gòu)成上,會(huì)將:new和:old看作triggering_table%ROWTYPE類型的記錄,但是,實(shí)際上它們并不是記錄。因此,那些能夠在記錄上正常執(zhí)行的操作,并不能在:new和:old上執(zhí)行。例如,不能將它們作為一個(gè)整體進(jìn)行賦值。只能對(duì)其中的各個(gè)字段分別賦值。

     

     

    view plaincopy to clipboardprint?
    CREATE OR REPLACE TRIGGER TempDelete  

    BEFORE DELETE ON temp_table  

    FOR EACH ROW  

    DECLARE  

    v_TempRec temp_table%ROWTYPE;  

    BEGIN  

    /* This is not a legal assignment, since :old is not truly

         a record. */

    v_TempRec := :old;  

       

    /* We can accomplish the same thing, however, by assigning

        the fields individually. */

    v_TempRec.char_col := :old.char_col;  

    v_TempRec.num_col := :old.num_col;  

    END TempDelete;  

    /
    CREATE OR REPLACE TRIGGER TempDelete

    BEFORE DELETE ON temp_table

    FOR EACH ROW

    DECLARE

    v_TempRec temp_table%ROWTYPE;

    BEGIN

    /* This is not a legal assignment, since :old is not truly

         a record. */

    v_TempRec := :old;

     

    /* We can accomplish the same thing, however, by assigning

        the fields individually. */

    v_TempRec.char_col := :old.char_col;

    v_TempRec.num_col := :old.num_col;

    END TempDelete;

    /

     

    REFERENCING子句

    還可以使用REFERENCING子句,為:old和:new換一個(gè)不同的名稱。該子句出現(xiàn)在觸發(fā)事件以后,WHEN子句以前。其語(yǔ)法如下:

     

    REFERENCING [OLD AS old_name] [NEW AS new_name]

     

    在觸發(fā)器主體中,可以使用:old_name和:new_name分別代替:old和:new。

     

    注意,在REFERENCING子句中關(guān)聯(lián)標(biāo)識(shí)符都不帶冒號(hào)。

     

    如下面這個(gè)例子所示


    view plaincopy to clipboardprint?
    CREATE OR REPLACE TRIGGER GenerateAuthorID  

    BEFORE INSERT OR UPDATE ON authors  

    REFERENCING new AS new_author  

    FOR EACH ROW  

    BEGIN  

    /* Fill in the ID field of authors with the next value from

         author_sequence. Since ID is a column in authors, :new.ID

         is a valid reference. */

    SELECT author_sequence.NEXTVAL  

        INTO :new_author.ID  

        FROM dual;  

    END GenerateAuthorID;  

    /
    CREATE OR REPLACE TRIGGER GenerateAuthorID

    BEFORE INSERT OR UPDATE ON authors

    REFERENCING new AS new_author

    FOR EACH ROW

    BEGIN

    /* Fill in the ID field of authors with the next value from

         author_sequence. Since ID is a column in authors, :new.ID

         is a valid reference. */

    SELECT author_sequence.NEXTVAL

        INTO :new_author.ID

        FROM dual;

    END GenerateAuthorID;

    /

     

    4、WHEN子句

    WHEN子句只能在行級(jí)觸發(fā)器中使用。如果在行級(jí)觸發(fā)器的定義中給出了WHEN子句,觸發(fā)器主體就只對(duì)滿足WHEN所定義條件的那些記錄行執(zhí)行。WHEN子句的基本形式如下:

     

    WHEN trigger_condition

     

    其中,trigger_condition是一個(gè)布爾表達(dá)式。每處理一行記錄,都會(huì)重新判斷該表達(dá)式的值。

     

    也可以在trigger_condition內(nèi)部使用:new和:old記錄,但是與REFERENCING子句一樣,在trigger_condition內(nèi)部使用:new和:old時(shí),不需要冒號(hào)。僅在觸發(fā)器主體中才需要使用冒號(hào)。

     

     

    5、觸發(fā)器謂詞

    可以在觸發(fā)器內(nèi)部使用3個(gè)布爾函數(shù),判斷觸發(fā)該觸發(fā)器的到底是什么操作。這3個(gè)謂詞分別是INSERTING、UPDATING和DELETING.


    使用方法如下面這個(gè)例子所示

     

    view plaincopy to clipboardprint?
    CREATE OR REPLACE TRIGGER LogInventoryChanges  

    BEFORE INSERT OR DELETE OR UPDATE ON inventory  

    FOR EACH ROW  

    DECLARE  

    v_ChangeType CHAR(1);  

    BEGIN  

    /* Use 'I' for an INSERT, 'D' for DELETE, and 'U' for UPDATE. */

    IF INSERTING THEN  

        v_ChangeType := 'I';  

    ELSIF UPDATING THEN  

        v_ChangeType := 'U';  

    ELSE  

        v_ChangeType := 'D';  

    END IF;  

       

    /* Record all the changes made to inventory in

         inventory_audit. Use SYSDATE to generate the timestamp, and

         USER to return the userid of the current user. */

    INSERT INTO inventory_audit  

        (change_type, changed_by, timestamp,  

         old_isbn, old_status, old_status_date, old_amount,  

         new_isbn, new_status, new_status_date, new_amount)  

    VALUES  

        (v_ChangeType, USER, SYSDATE,  

         :old.isbn, :old.status, :old.status_date, :old.amount,  

         :new.isbn, :new.status, :new.status_date, :new.amount);  

    END LogInventoryChanges;  

    /
    CREATE OR REPLACE TRIGGER LogInventoryChanges

    BEFORE INSERT OR DELETE OR UPDATE ON inventory

    FOR EACH ROW

    DECLARE

    v_ChangeType CHAR(1);

    BEGIN

    /* Use 'I' for an INSERT, 'D' for DELETE, and 'U' for UPDATE. */

    IF INSERTING THEN

        v_ChangeType := 'I';

    ELSIF UPDATING THEN

        v_ChangeType := 'U';

    ELSE

        v_ChangeType := 'D';

    END IF;

     

    /* Record all the changes made to inventory in

         inventory_audit. Use SYSDATE to generate the timestamp, and

         USER to return the userid of the current user. */

    INSERT INTO inventory_audit

        (change_type, changed_by, timestamp,

         old_isbn, old_status, old_status_date, old_amount,

         new_isbn, new_status, new_status_date, new_amount)

    VALUES

        (v_ChangeType, USER, SYSDATE,

         :old.isbn, :old.status, :old.status_date, :old.amount,

         :new.isbn, :new.status, :new.status_date, :new.amount);

    END LogInventoryChanges;

    /

     

     

    6、INSTEAD-OF觸發(fā)器

    INSTEAD-OF觸發(fā)器僅可以定義在視圖上(關(guān)系型的或?qū)ο螅⑶宜鼈兛梢蕴娲c(diǎn)火它們的DML語(yǔ)句進(jìn)行點(diǎn)火。INSTEAD-OF觸發(fā)器必須是行級(jí)的。

     

     

    7、觸發(fā)器的限制

    觸發(fā)器的主體是一個(gè)PL/SQL塊。在PL/SQL塊中可以使用的所有語(yǔ)句在觸發(fā)器主體中都是合法的,但是要受到下面限制的約束:

     

    觸發(fā)器不應(yīng)該使用事務(wù)控制語(yǔ)句—COMMIT、ROLLBACK或SAVEPOINT。觸發(fā)器作為觸發(fā)語(yǔ)句執(zhí)行的一部分被點(diǎn)火,它和觸發(fā)語(yǔ)句在同一個(gè)事務(wù)中。當(dāng)觸發(fā)語(yǔ)句被提交或撤回提交時(shí),觸發(fā)器的工作也相應(yīng)被提交會(huì)撤回提交。
    由觸發(fā)器主體調(diào)用的任何過程和函數(shù)都不能使用事務(wù)控制語(yǔ)句。
    觸發(fā)器主體不能聲明任何LONG或者LONG RAW變量。而且,:new和:old不能指向定義觸發(fā)器的表中的LONG和LONG RAW列。
    觸發(fā)器主體可以訪問的表有所限制。

    觸發(fā)器P-Code

    當(dāng)包或者子程序存儲(chǔ)在數(shù)據(jù)字典中時(shí),存儲(chǔ)的除了該對(duì)象的源代碼還有經(jīng)過編譯的p-code。但是對(duì)于觸發(fā)器來說就不是這樣的。在數(shù)據(jù)字典中唯一存儲(chǔ)的是觸發(fā)器的源代碼,而不是p-code。結(jié)果,每次當(dāng)從數(shù)據(jù)字典中重新讀出觸發(fā)器時(shí),必須要進(jìn)行編譯。這對(duì)觸發(fā)器的定義和使用的方式不會(huì)帶來什么影響,但是會(huì)影響觸發(fā)器的性能。

     

     

    8、系統(tǒng)觸發(fā)器

    我們前面所看到的DML觸發(fā)器和INSTEAD-OF觸發(fā)器都是基于DML事件。而另一方面,系統(tǒng)觸發(fā)器的激活則是基于兩種不同的事件:DDL事件或數(shù)據(jù)庫(kù)事件。DDL事件包括CREATE、ALTER或DROP語(yǔ)句,而數(shù)據(jù)庫(kù)事件包括數(shù)據(jù)庫(kù)服務(wù)器的啟動(dòng)/關(guān)閉事件,用戶的登陸/斷開事件,以及服務(wù)器錯(cuò)誤。創(chuàng)建系統(tǒng)觸發(fā)器的語(yǔ)法如下:

     


    view plaincopy to clipboardprint?
    CREATE [OR REPLACE] TRIGGER [schema.]trigger_name  

    {BEFORE | AFTER}  

    {ddl_event_list | database_event_list}  

    ON {DATABASE | [schema.]SCHEMA}  

    [when_clause]  

    Trigger_body;
    CREATE [OR REPLACE] TRIGGER [schema.]trigger_name

    {BEFORE | AFTER}

    {ddl_event_list | database_event_list}

    ON {DATABASE | [schema.]SCHEMA}

    [when_clause]

    Trigger_body;

     

    其中,ddl_event_list是由OR關(guān)鍵字隔開的一個(gè)或多個(gè)DDL事件,database_event_list則是由OR關(guān)鍵字隔開的一個(gè)或多個(gè)數(shù)據(jù)庫(kù)事件。

     

    注意:不能創(chuàng)建INSTEAD-OF系統(tǒng)級(jí)觸發(fā)器。

     

    通過子句ON {DATABASE | [schema.]SCHEMA}我們可以指定這個(gè)系統(tǒng)觸發(fā)器是定義在數(shù)據(jù)庫(kù)級(jí)上還是模式級(jí)上。只要發(fā)生了激活事件,數(shù)據(jù)庫(kù)級(jí)觸發(fā)器就會(huì)激活。而只有激活事件發(fā)生在某個(gè)具體模式中,相應(yīng)的模式級(jí)觸發(fā)器才會(huì)激活。如果使用SCHEMA關(guān)鍵字的時(shí)候沒有定義某個(gè)具體模式的名稱,那么默認(rèn)設(shè)置為擁有這個(gè)觸發(fā)器的模式。

     

     

    9、修改觸發(fā)器狀態(tài)和刪除觸發(fā)器

     

    啟動(dòng)或禁用觸發(fā)器

     

    ALTER TRIGGER trigger_name {DISABLE | ENABLE};

     

    刪除觸發(fā)器

     

    DROP TRIGGER trigger_name;

     

    還可以使用ALTER TABLE命令,并附加使用ENABLE ALL TRIGGERS或DISABLE ALL TRIGGERS子句,同時(shí)將某一個(gè)表上的所有觸發(fā)器開啟或關(guān)閉。

     

    ALTER TABLE table_name {ENABLE | DISABLE} ALL TRIGGERS;

     

    可以通過user_triggers來查看相應(yīng)觸發(fā)器信息。

     

     

    10、變化表和限制表

    觸發(fā)器主體(trigger body)可以訪問的表和列上有一些限制。在定義這些限制以前,我們先看兩個(gè)概念—變化表和限制表。

    “變化表”(mutating table)是被DML語(yǔ)句正在修改的表。對(duì)于觸發(fā)器而言,它就是定義觸發(fā)器的表。需要作為DELETE CASCADE參考完整性限制(referential integrity constraints)的結(jié)果進(jìn)行更新的表也是變化的(mutating)。

    “限制表”(constraining table)是可能需要對(duì)參考完整性限制執(zhí)行讀操作的表。

     

    為了更好的理解定義,我們看下面這個(gè)例子

     

    view plaincopy to clipboardprint?
    CREATE TABLE registered_students (  

    student_id NUMBER(5) NOT NULL,  

    department CHAR(3)   NOT NULL,  

    course     NUMBER(3) NOT NULL,  

    grade      CHAR(1),  

    CONSTRAINT rs_grade  

        CHECK (grade IN ('A', 'B', 'C', 'D', 'E')),  

    CONSTRAINT rs_student_id  

        FOREIGN KEY (student_id) REFERENCES students (id),  

    CONSTRAINT rs_department_course  

        FOREIGN KEY (department, course)  

        REFERENCES classes (department, course)  

    );  

    --...
    CREATE TABLE registered_students (

    student_id NUMBER(5) NOT NULL,

    department CHAR(3)   NOT NULL,

    course     NUMBER(3) NOT NULL,

    grade      CHAR(1),

    CONSTRAINT rs_grade

        CHECK (grade IN ('A', 'B', 'C', 'D', 'E')),

    CONSTRAINT rs_student_id

        FOREIGN KEY (student_id) REFERENCES students (id),

    CONSTRAINT rs_department_course

        FOREIGN KEY (department, course)

        REFERENCES classes (department, course)

    );

    --...

     

    registered_students有兩個(gè)聲明的參考完整性限制。

    Students和classes都是registered_students的限制表。

     

    觸發(fā)器主體中的SQL不允許進(jìn)行:

    讀取或修改觸發(fā)語(yǔ)句(triggering statement)的任何變化表。這些表包括觸發(fā)表(triggering table )自己。
    讀取或修改觸發(fā)表(triggering table)的限制表中的主鍵(primary)、唯一列值(unique)或外鍵(foreign key)列。但是如果需要的話,可以修改其他列。

    轉(zhuǎn)載:http://blog.csdn.net/wh62592855/archive/2009/10/27/4735701.aspx

      本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
      轉(zhuǎn)藏 分享 獻(xiàn)花(0

      0條評(píng)論

      發(fā)表

      請(qǐng)遵守用戶 評(píng)論公約

      類似文章 更多

      主站蜘蛛池模板: 韩国免费A级毛片久久| 色偷偷人人澡久久超碰97| 草裙社区精品视频播放| 亚洲AV熟妇在线观看| 亚洲国产精品成人网址| 亚洲欧美高清在线精品一区二区| 一卡2卡三卡4卡免费网站| 亚洲日本VA午夜在线电影| a级国产乱理伦片在线观看al| 亚洲欧美中文字幕日韩一区二区| 亚洲制服丝袜系列AV无码| 午夜DY888国产精品影院| 天码AV无码一区二区三区四区| 日本一区二区不卡精品| 亚洲精品高清国产一久久| 国产成AV人片久青草影院| 成人小说亚洲一区二区三区| 国产小受被做到哭咬床单GV| 国产精品情侣呻吟对白视频| 在线理论三级午夜电影| 超频97人妻在线视频| 亚洲性线免费观看视频成熟| 国产精品久久露脸蜜臀| 精品国产亚洲一区二区三区| 国产美女被遭强高潮免费一视频| 国产精品乱码久久久久久软件| 无码免费大香伊蕉在人线国产| 少妇精品无码一区二区三区| 国产精品美脚玉足脚交欧美| 日韩精品国产二区三区| 国产亚洲AV无码AV男人的天堂| 久久人人97超碰精品| 在线国产精品中文字幕| 欧美亚洲国产一区二区三区| 人妻精品动漫H无码中字| 国产凹凸在线一区二区| 色欲久久人妻内射| 亚洲色最新高清AV网站| av中文字幕在线二区| 人妻系列无码专区无码中出| 亚洲国产成人AⅤ毛片奶水|