Oracle使用insert觸發(fā)器遇到的問題及解決
Oracle使用insert觸發(fā)器遇到的問題
首先TRIGGER基本語句
create or replace trigger 'trigger_name'--觸發(fā)器名稱 before insert --或 after insert (觸發(fā)時(shí)機(jī)) --關(guān)鍵字before和after用于標(biāo)識(shí)觸發(fā)時(shí)間,顧名思義,before代表觸發(fā)器里面的命令在DML修改數(shù)據(jù)之前執(zhí)行, --after代表觸發(fā)器里面的命令在DML修改數(shù)據(jù)之后執(zhí)行。 REFERENCING new as new --或old as old (用于觸發(fā)器中參數(shù)使用) --注:before中的new指的是當(dāng)前插入的集,after中的old指的是當(dāng)前插入的集 FOR EACH ROW --指當(dāng)前觸發(fā)器為行級(jí)觸發(fā)器(行級(jí)觸發(fā)器相對(duì)于語句級(jí)觸發(fā)器) --行級(jí)觸發(fā)器能夠通過 :new.屬性 和 :old.屬性等獲得update或者insert發(fā)生之前的新值和發(fā)生值之后的舊值。 declare --聲明變量…… BEGIN END;
關(guān)于行級(jí)觸發(fā)器的 :new.屬性 和 :old.屬性使用
TRIGGER TONGBUJIAYI_SFZH before DELETE OR UPDATE of D_SFZH ON T_DA_JKDA_RKXZL REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW BEGIN IF UPDATING THEN insert into T_DA_JKDA_RKXZL_GWANDJY(ID,D_GRDABH,P_RGID,D_SFZH,D_SFZHXGQ,D_DATZXGH,D_XM,D_BGSJ,D_BGZT) VALUES (SYS_GUID(),:OLD.D_GRDABH,:OLD.P_RGID,:OLD.D_SFZH,:NEW.D_SFZH,'',:OLD.D_XM,sysdate,'2'); ELSIF DELETING THEN insert into T_DA_JKDA_RKXZL_GWANDJY(ID,D_GRDABH,P_RGID,D_SFZH,D_SFZHXGQ,D_DATZXGH,D_XM,D_BGSJ,D_BGZT) VALUES (SYS_GUID(),:OLD.D_GRDABH,:OLD.P_RGID,:OLD.D_SFZH,'','',:OLD.D_XM,sysdate,'1'); END IF; END;
在Oracle中執(zhí)行DML語句的時(shí)候是需要顯示進(jìn)行提交操作的。
當(dāng)我們進(jìn)行插入的時(shí)候,會(huì)觸發(fā)觸發(fā)器執(zhí)行對(duì)觸發(fā)器作用表和擴(kuò)展表的種種操作,
但是這個(gè)時(shí)候觸發(fā)器和插入語句是在同一個(gè)事務(wù)管理中的,因此在插入語句沒有被提交的情況下,我們無法對(duì)觸發(fā)器作用表進(jìn)行其他額外的操作。
如果執(zhí)行其他額外的操作則會(huì)拋出如下異常信息。
ORA-04091:表*****發(fā)生了變化觸發(fā)器/函數(shù)不能讀它
此次觸發(fā)器產(chǎn)生場(chǎng)景:
一個(gè)身份證號(hào)及個(gè)人信息導(dǎo)入到系統(tǒng)中,在系統(tǒng)中修改了關(guān)于疫情的信息。
但再次導(dǎo)入此人的信息時(shí)(每次導(dǎo)入的信息都不包含關(guān)于疫情的信息),則需要同步。
由此引入觸發(fā)器,觸發(fā)條件為insert
TRIGGER DETECTION_USERS_SYN_VACCINE
BEFORE INSERT ON DETECTION_USERS
REFERENCING new as new
FOR EACH ROW
DECLARE --oracle中聲明多個(gè)屬性時(shí)只需要用一次DECLARE即可
V_ID DETECTION_USERS.ID%TYPE;--此處聲明的屬性是按照DETECTION_USERS表中的屬性聲明
V_IS_VACCINATION DETECTION_USERS.IS_VACCINATION%TYPE;
V_VACCINE1 DETECTION_USERS.VACCINE1%TYPE;
V_VACCINE2 DETECTION_USERS.VACCINE2%TYPE;
V_VACCINE3 DETECTION_USERS.VACCINE3%TYPE;
V_NUM_VACCINATION DETECTION_USERS.NUM_VACCINATION%TYPE;
--聲明游標(biāo)查詢此人添加之前的接種信息
CURSOR latests is
SELECT ID,
IS_VACCINATION,
VACCINE1,
VACCINE2,
VACCINE3,
NUM_VACCINATION
FROM (SELECT t.*, row_number() over(order by nvl(zdrq, '0') DESC) rn
from (SELECT *
FROM (SELECT ID,
IS_VACCINATION,
VACCINE1,
VACCINE2,
VACCINE3,
NUM_VACCINATION,
(CASE
WHEN (VACCINE3 IS NOT null) THEN
VACCINE3
WHEN (VACCINE2 IS NOT null) THEN
VACCINE2
WHEN (VACCINE1 IS NOT null) THEN
VACCINE1
ELSE
''
END) AS zdrq
FROM DETECTION_USERS
WHERE "IDENTITY" = :new."IDENTITY"
AND IS_VACCINATION IS NOT NULL)) t)
WHERE rn = 1;
BEGIN
OPEN latests;
FETCH latests
INTO V_ID,
V_IS_VACCINATION,
V_VACCINE1,
V_VACCINE2,
V_VACCINE3,
V_NUM_VACCINATION;
---打印語句
-- DBMS_OUTPUT.PUT_LINE('latests===' || V_ID || '**' || V_IS_VACCINATION || '**' ||
-- V_VACCINE1 || '**' || V_VACCINE2 || '**' ||
-- V_VACCINE3 || '**' || V_NUM_VACCINATION);
-- DBMS_OUTPUT.PUT_LINE('new===' || :new.ID || '**' || :new.IS_VACCINATION || '**' ||
-- :new.VACCINE1 || '**' || :new.VACCINE2 || '**' ||
-- :new.VACCINE3 || '**' || :new.NUM_VACCINATION);
IF INSERTING THEN
:new.IS_VACCINATION := V_IS_VACCINATION;--將打開的cursor賦值到新插入的這列數(shù)值中
:new.VACCINE1 := V_VACCINE1;
:new.VACCINE2 := V_VACCINE2;
:new.VACCINE3 := V_VACCINE3;
:new.NUM_VACCINATION := V_NUM_VACCINATION;
END IF;
--FETCH NEXT FROM from_inserted INTOV_ID,V_IS_VACCINATION,V_VACCINE1,V_VACCINE2, V_VACCINE3,V_NUM_VACCINATION;
--循環(huán),此處cursor只有一條,不需要。
CLOSE latests;
END;總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
window10 安裝Oracle19C 和SQL Developer 的圖文教程
這篇文章主要介紹了window10 安裝Oracle19C 和SQL Developer 教程(圖文詳解),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
如何解決Oracle數(shù)據(jù)表入庫中文亂碼問題
Oracle數(shù)據(jù)庫在處理中文數(shù)據(jù)時(shí),經(jīng)常會(huì)遇到亂碼問題,導(dǎo)致數(shù)據(jù)無法正常顯示和處理,這是因?yàn)镺racle數(shù)據(jù)庫默認(rèn)的字符集為US7ASCII,無法識(shí)別中文字符,通過修改數(shù)據(jù)庫,客戶端和應(yīng)用程序字符集,將數(shù)據(jù)轉(zhuǎn)換為正確的字符集,可以避免亂碼問題2024-02-02
ORACLE應(yīng)用經(jīng)驗(yàn)(1)
ORACLE應(yīng)用經(jīng)驗(yàn)(1)...2007-03-03
通過 plsql 連接遠(yuǎn)程 Oracle數(shù)據(jù)庫的多種方法
這篇文章主要介紹了通過 plsql 連接遠(yuǎn)程 Oracle的方法,通過plsql 工具和 oracle client(不是即時(shí)客戶端 instantclient) 的方式來連接 Oracle,這是方法之一,還有其中一種方法感興趣的朋友跟隨小編一起看看吧2021-08-08
解讀Oracle中代替like進(jìn)行模糊查詢的方法instr(更高效)
這篇文章主要介紹了解讀Oracle中代替like進(jìn)行模糊查詢的方法instr(更高效),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

