久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 艾雪溪 2009-12-11

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

觸發(fā)器也是一種帶名的PL/SQL塊。觸發(fā)器類似于過程和函數(shù),,因為它們都是擁有聲明,、執(zhí)行和異常處理過程的帶名PL/SQL塊。與包類似,,觸發(fā)器必須存儲在數(shù)據(jù)庫中并且不能被塊進行本地化聲明,。

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

 

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

 


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

 

 

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

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

2)對受該語句影響的每一行記錄

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

執(zhí)行該語句本身

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

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

 

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

 

3,、行級觸發(fā)器中的關聯(lián)標識符

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

 

Triggering_table%ROWTYPE

 

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

 

:new.field

 

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

 

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

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

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

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

 

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

 

偽記錄

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

 

 

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換一個不同的名稱,。該子句出現(xiàn)在觸發(fā)事件以后,WHEN子句以前,。其語法如下:

 

REFERENCING [OLD AS old_name] [NEW AS new_name]

 

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

 

注意,,在REFERENCING子句中關聯(lián)標識符都不帶冒號,。

 

如下面這個例子所示


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

 

WHEN trigger_condition

 

其中,,trigger_condition是一個布爾表達式,。每處理一行記錄,都會重新判斷該表達式的值,。

 

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

 

 

5,、觸發(fā)器謂詞

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


使用方法如下面這個例子所示

 

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ā)器僅可以定義在視圖上(關系型的或?qū)ο螅⑶宜鼈兛梢蕴娲c火它們的DML語句進行點火,。INSTEAD-OF觸發(fā)器必須是行級的,。

 

 

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

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

 

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

觸發(fā)器P-Code

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

 

 

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

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

 


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關鍵字隔開的一個或多個DDL事件,database_event_list則是由OR關鍵字隔開的一個或多個數(shù)據(jù)庫事件,。

 

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

 

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

 

 

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

 

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

 

ALTER TRIGGER trigger_name {DISABLE | ENABLE};

 

刪除觸發(fā)器

 

DROP TRIGGER trigger_name;

 

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

 

ALTER TABLE table_name {ENABLE | DISABLE} ALL TRIGGERS;

 

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

 

 

10,、變化表和限制表

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

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

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

 

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

 

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有兩個聲明的參考完整性限制,。

Students和classes都是registered_students的限制表,。

 

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

讀取或修改觸發(fā)語句(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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多