INSTEADOF觸發(fā)器--==============================INSTEADOF觸發(fā)器常用于管理編寫不可更新的視圖,INSTEAD-OF觸發(fā)器必須是行級的。可以用INSTEADOF觸發(fā)器來解釋INSERT、UPDATE和DELETE語句,并用備用的程序代碼替換那些指令。一、不可更新視圖基于下列情形創(chuàng)建的視圖,不可直接對其進行DML操作使用了集合操" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

PL/SQL --> INSTEAD OF 觸發(fā)器

系統(tǒng) 2356 0

--==============================

-- PL/SQL --> INSTEAD OF 觸發(fā)器

--==============================

?

??? INSTEAD OF 觸發(fā)器常用于管理編寫不可更新的視圖, INSTEAD-OF 觸發(fā)器必須是行級的。

??? 可以用 INSTEAD OF 觸發(fā)器來解釋 INSERT UPDATE DELETE 語句,并用備用的程序代碼替換那些指令。

?

一、不可更新視圖

??? 基于下列情形創(chuàng)建的視圖,不可直接對其進行 DML 操作

??????? 使用了集合操作運算符 (UNION,UNION ALL ,INTERSECT,MINUS)

??????? 使用了分組函數(shù) (MIN,MAX,SUM,AVG)

??????? 使用了 GROUP BY ,CONNECT BY ,START WITH 子句

??????? 使用了 DISTINCT 關(guān)鍵字

??????? 使用了連接查詢

??? ? 對于基于上述情況創(chuàng)建的視圖,不能對其直接執(zhí)行 DML ,但可以在該視圖上創(chuàng)建 INSTEAD OF 觸發(fā)器來間接執(zhí)行 DML

???

二、創(chuàng)建 INSTEAD OF 觸發(fā)器的語法

??? CREATE [OR REPLACE] TRIGGER trigger_name

??? INSTEAD OF { dml_statement }

??? ON { object_name | database | schema}

??? FOR EACH ROW

??? [WHEN (logical_expression)]

??? [DECLARE]

??????? declaration_statements ;

??? BEGIN

??????? execution_statements ;

??? END [trigger_name] ;

??? /

?

三、創(chuàng)建視圖

??? -- 在下面創(chuàng)建的視圖中,由于使用了連接查詢,因此視圖將不可更新

??????? CREATE OR REPLACE VIEW vw_dept_emp

??????? AS

??????? ? SELECT deptno , d . dname , e . empno , e . ename

??????? ? FROM dept d

??????? ? JOIN emp e

??????? ? USING ( deptno );

???

??? -- 從數(shù)據(jù)字典 (user_updatable_columns) 中查詢某一視圖哪些列是可更新或不可更新的

??????? scott@ORCL > col owner format a15

??????? scott@ORCL > select * from user_updatable_columns where table_name = 'VW_DEPT_EMP' ; ?

?

??????? OWNER ?????????? TABLE_NAME ???????????????????? COLUMN_NAME ???? UPD INS DEL

??????? --------------- ------------------------------ --------------- --- --- ---

??????? SCOTT ?????????? VW_DEPT_EMP ???????????????? ??? DEPTNO ????????? YES YES YES

??????? SCOTT ?????????? VW_DEPT_EMP ??????????????????? DNAME ?????????? NO ? NO ? NO ?? -- 可以看到列 DNAME 不能執(zhí)行 DML

??????? SCOTT ?????????? VW_DEPT_EMP ??????????????????? EMPNO ?????????? YES YES YES

??????? SCOTT ?????????? VW_DEPT_EMP ??????????????????? ENAME ?????????? YES YES YES

??????? ?

??? -- 嘗試更新視圖時,更新失敗

??????? scott@ORCL > update vw_dept_emp set dname = 'Developement' where deptno = 10 ;

??????? update vw_dept_emp set dname = 'Developement' where deptno = 10

??????????????????????????? ?? *

??????? ERROR at line 1 :

??????? ORA - 01779 : cannot modify a column which maps to a non key - preserved table ??????

??? ?

??????? scott@ORCL > update vw_dept_emp set ename = 'Henry' where empno = 7369 ;

?

??????? 1 row updated .

?

??????? scott@ORCL > select empno , ename , job from emp where empno = 7369 ;

?

??????????? ? EMPNO ENAME ????? JOB

??????? ---------- ---------- ---------

??????????? ? 7369 Henry ????? CLERK

??? ?

??? -- 創(chuàng)建一個基于 UPDATE INSTEAD OF 觸發(fā)器

??????? CREATE OR REPLACE TRIGGER tr_vw_dept_emp

??????? INSTEAD OF UPDATE

??????? ON vw_dept_emp

??????? FOR EACH ROW

??????? BEGIN

??????? ? UPDATE dept

??????? ? SET dname =: new . dname

??????? ? WHERE deptno =: old . deptno ;

??????? END ;

?

??? -- 更新視圖

??????? scott@ORCL > update vw_dept_emp set dname = 'Developement' where deptno = 20 ;

?

??????? 4 rows updated .

???

??? -- 驗證更新后的結(jié)果

??????? scott@ORCL > select * from vw_dept_emp where rownum < 2 and deptno = 20 ;

?

??????????? DEPTNO DNAME ?????????????? EMPNO ENAME

??????? ---------- -------------- ---------- ----------

??????????????? 20 Developement ?? ?????? 7369 Henry

?

??????? scott@ORCL > select * from dept where deptno = 20 ;

?

??????????? DEPTNO DNAME ????????? LOC

??????? ---------- -------------- -------------

??????????????? 20 Developement ?? DALLAS ??? ?

?

四、 INSTEAD OF 觸發(fā)器的應(yīng)用

??? 在工作中,有時候需要將兩個或多個表中的字段進行同步的問題。即假定有表 A B ,表 A 中的字段 COLa 和表 B 中的字段 COLb 需要時時保持同

??? 步,當(dāng)表 A COLa 被更新時,需要將更新的內(nèi)容同步到表 B COLb 中,反之,當(dāng)表 B COLb 被更新時,需要將 COLb 的內(nèi)容更新到 A 表的 COLa 中。

??? 對于這樣的問題,按照一般的想法是在表 A 和表 B 分別創(chuàng)建觸發(fā)器來使之保持同步,但實際上表 A 和表 B 上的觸發(fā)器將會被迭代觸發(fā),即 A 表的

??? 更新將觸發(fā) B 表上的觸發(fā)器,而 B 表上的觸發(fā)器反過來又觸發(fā) A 上的觸發(fā)器,最終的結(jié)果是導(dǎo)致變異表的產(chǎn)生。基于此,我們可以使用 INSTEAD

??? OF 觸發(fā)器完成此項任務(wù),下面給出全部過程。

???

??? -- 分別創(chuàng)建表 tb_a,tb_b 并插入記錄

??????? scott@ORCL > create table tb_a ( ID int , COLa varchar2 ( 40 ));

?

??????? scott@ORCL > create table tb_b ( ID int , COLb varchar2 ( 40 ));

?

??????? scott@ORCL > insert into tb_a select 1 , 'Robinson' from dual ;

?

??????? scott@ORCL > insert into tb_b select 1 , 'Jackson' from dual ;

?

??????? scott@ORCL > commit ;

?

??? -- 在表 tb_a 上創(chuàng)建觸發(fā)器

??????? CREATE OR REPLACE TRIGGER tr_tb_a

??????? ? BEFORE UPDATE ON tb_a

??????? ? FOR EACH ROW

??????? DECLARE

??????? ? lv_newcol ??? VARCHAR2 ( 40 );

??????? ? lv_oldcol ??? VARCHAR2 ( 40 );

??????? BEGIN

??????? ? lv_newcol := : new . COLa ;

??????? ? lv_oldcol := : old . COLa ;

??????? ? IF lv_newcol <> lv_oldcol THEN

??????????? UPDATE tb_b

??????????? ?? SET COLb = : new . COLa

??????????? ? WHERE ID = : new . ID ;

??????? ? END IF ;

??????? ? DBMS_OUTPUT . PUT_LINE ( lv_oldcol || '=>' || lv_newcol );

??????? END ;

???

??? -- 更新表 tb_a 時,表 tb_b 的字段也被更新

??????? scott@ORCL > update tb_a set COLa = 'Willson' where ID = 1 ;

??????? Robinson => Willson

?

??????? scott@ORCL > select * from tb_b ;

?

??????????????? ID COLB

??????? ---------- ----------------------------------------

??????????????? ? 1 Willson

?

??? -- 在表 B 上創(chuàng)建觸發(fā)器

??????? CREATE OR REPLACE TRIGGER tr_tb_b

??????? ? BEFORE UPDATE ON tb_b

??????? ? FOR EACH ROW

??????? DECLARE

??????? ? lv_newcol ??? VARCHAR2 ( 40 );

??????? ? lv_oldcol ??? VARCHAR2 ( 40 );

??????? BEGIN

??????? ? lv_newcol := : new . COLb ;

??????? ? lv_oldcol := : old . COLb ;

??????? ? IF lv_newcol <> lv_oldcol THEN

??????????? UPDATE tb_a

??????????? ?? SET COLa = : new . COLb

??????????? ? WHERE ID = : new . ID ;

??????? ? END IF ;

??????? ? DBMS_OUTPUT . PUT_LINE ( lv_oldcol || '=>' || lv_newcol );

??????? END ;

???

??? -- 更新表 tb_b 時,出現(xiàn)了表變異的提示,同樣更新表 tb_a 時也會出現(xiàn)類似的提示

??????? scott@ORCL > update tb_b set COLb = 'Other' where ID = 1 ;

??????? update tb_b set COLb = 'Other' where ID = 1

??????????? ?? *

??????? ERROR at line 1 :

??????? ORA - 04091 : table SCOTT . TB_B is mutating , trigger / function may not see it

??????? ORA - 06512 : at "SCOTT.TR_TB_A" , line 8

??????? ORA - 04088 : error during execution of trigger 'SCOTT.TR_TB_A'

??????? ORA - 06512 : at "SCOTT.TR_TB_B" , line 8

??????? ORA - 04088 : error during execution of trigger 'SCOTT.TR_TB_B'

?

??? -- 禁用觸發(fā)器

??????? scott@ORCL > alter trigger tr_tb_a disable ;

?

??????? scott@ORCL > alter trigger tr_tb_b disable ;

?

??? -- 分別在表 tb_a tb_b 上創(chuàng)建視圖

??????? scott@ORCL > create view vw_tb_a as select * from tb_a ;

?

??????? scott@ORCL > create view vw_tb_b as select * from tb_b ;

???

??? -- 基于視圖 vw_tb_a 創(chuàng)建 instead of 觸發(fā)器

??????? CREATE OR REPLACE TRIGGER tr_vw_tb_a

??????? ? INSTEAD OF UPDATE ON vw_tb_a

??????? ? FOR EACH ROW

??????? DECLARE

??????? ? lv_newcol ??? VARCHAR2 ( 40 );

??????? ? lv_oldcol ??? VARCHAR2 ( 40 );

??????? BEGIN

??????? ? lv_newcol := : new . COLa ;

??????? ? lv_oldcol := : old . COLa ;

??????? ? IF lv_newcol <> lv_oldcol THEN

??????????? UPDATE tb_a

??????????? ? SET COLa = : new . COLa

??????????? WHERE ID = : new . ID ;

???????????

??????????? UPDATE tb_b

??????????? ? SET COLb = : new . cola

??????????? WHERE ID =: new . ID ;

??????? ? END IF ;

??????? ? DBMS_OUTPUT . PUT_LINE ( lv_oldcol || '=>' || lv_newcol );

??????? END ;

???

??? -- 基于視圖 vw_tb_b 創(chuàng)建 instead of 觸發(fā)器

??????? CREATE OR REPLACE TRIGGER tr_vw_tb_b

??????? ? INSTEAD OF UPDATE ON vw_tb_b

??????? ? FOR EACH ROW

??????? DECLARE

??????? ? lv_newcol ??? VARCHAR2 ( 40 );

??????? ? lv_oldcol ??? VARCHAR2 ( 40 );

??????? BEGIN

??????? ? lv_newcol := : new . COLb ;

??????? ? lv_oldcol := : old . COLb ;

??????? ? IF lv_newcol <> lv_oldcol THEN

??????????? UPDATE tb_a

??????????? ? SET COLa = : new . COLb

??????????? WHERE ID = : new . ID ;

???????????

??????????? UPDATE tb_b

??????????? ? SET COLb = : new . colb

??????????? WHERE ID =: new . ID ;

??????? ? END IF ;

??????? ? DBMS_OUTPUT . PUT_LINE ( lv_oldcol || '=>' || lv_newcol );

??????? END ; ???

???

??? -- 對視圖進行更新,驗證成功

??????? scott@ORCL > update vw_tb_a set COLa = 'Many' where ID = 1 ;

??????? Willson => Many

?

??????? scott@ORCL > select * from tb_b ;

?

??????????????? ID COLB

??????? ---------- ----------------------------------------

??????????????? ? 1 Many

?

??????? scott@ORCL > update vw_tb_b set COLb = 'Much' where ID = 1 ;

??????? Many => Much

?

??????? scott@ORCL > select * from tb_a ;

?

??????????????? ID COLA

??????? ---------- ----------------------------------------

??????????????? ? 1 Much

???

五、總結(jié)

??? 視圖創(chuàng)建時未指定 WITH CHECK OPTION 選項

??? INSTEAD OF 觸發(fā)器只適用于視圖

??? 基于視圖的 INSTEAD OF 觸發(fā)器不能指定 BEFORE AFTER 選項

??? INSTEAD OF 觸發(fā)器,必須指定 FOR EACH ROW

??? 當(dāng)創(chuàng)建的視圖被重新定義之后,基于視圖上創(chuàng)建的觸發(fā)器將需要重新定義

?

六、更多參考

有關(guān) SQL 請參考

??????? SQL 基礎(chǔ)--> 子查詢

??????? SQL 基礎(chǔ)--> 多表查詢

SQL 基礎(chǔ)--> 分組與分組函數(shù)

SQL 基礎(chǔ)--> 常用函數(shù)

SQL 基礎(chǔ)--> ROLLUP 與CUBE 運算符實現(xiàn)數(shù)據(jù)匯總

SQL 基礎(chǔ)--> 層次化查詢(START BY ... CONNECT BY PRIOR)

?

??? 有關(guān) PL/SQL 請參考

??????? PL/SQL --> 語言基礎(chǔ)

PL/SQL --> 流程控制

PL/SQL --> 存儲過程

PL/SQL --> 函數(shù)

PL/SQL --> 游標(biāo)

PL/SQL --> 隱式游標(biāo)(SQL%FOUND)

PL/SQL --> 異常處理(Exception)

PL/SQL --> PL/SQL 記錄

PL/SQL --> 包的創(chuàng)建與管理

PL/SQL --> 包重載、初始化

PL/SQL --> DBMS_DDL 包的使用

PL/SQL --> DML 觸發(fā)器

PL/SQL --> INSTEAD OF 觸發(fā)器

?

?

???

PL/SQL --> INSTEAD OF 觸發(fā)器


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 99这里只有精品视频 | 九九影院理论片 | 三级全黄a | 天堂色综合 | 日韩三级不卡 | 91免费大全| 波多野吉衣一区二区 | 男人天堂网www | 精品成人免费一区二区在线播放 | 亚洲成人一区二区三区 | 中文字幕精品一区二区三区精品 | 亚洲日本中文字幕永久 | 国产精品日韩 | 中文字幕伊人久久网 | 久久精品一区二区国产 | 播五月婷婷 | 国产一区二区久久 | 啪啪免费视频网站 | 毛片99| 日韩欧美在线视频播放 | 午夜激情视频在线观看 | 天天操操操操操操 | 日本久久久久久 | 日本一区二区三区高清不卡 | 91xxx在线观看| 91视频电影| 五月婷婷狠狠干 | 性色成人网 | 亚洲精品成人 | 福利视频1000 | 亚洲一区在线免费观看 | 天天舔天天 | 毛片一级在线 | www.国产精| 国产精品国色综合久久 | 国产亚洲精品久久久久久打不开 | 99热在线国产 | 色婷婷精品国产一区二区三区 | a黄视频| 国变精品美女久久久久av爽 | 色伊人网 |