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)識觸發(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ā)器為行級觸發(fā)器(行級觸發(fā)器相對于語句級觸發(fā)器) --行級觸發(fā)器能夠通過 :new.屬性 和 :old.屬性等獲得update或者insert發(fā)生之前的新值和發(fā)生值之后的舊值。 declare --聲明變量…… BEGIN END;
關(guān)于行級觸發(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í)候,會觸發(fā)觸發(fā)器執(zhí)行對觸發(fā)器作用表和擴(kuò)展表的種種操作,
但是這個(gè)時(shí)候觸發(fā)器和插入語句是在同一個(gè)事務(wù)管理中的,因此在插入語句沒有被提交的情況下,我們無法對觸發(fā)器作用表進(jìn)行其他額外的操作。
如果執(zhí)行其他額外的操作則會拋出如下異常信息。
ORA-04091:表*****發(fā)生了變化觸發(fā)器/函數(shù)不能讀它
此次觸發(fā)器產(chǎn)生場景:
一個(gè)身份證號及個(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)文章
CentOS6.2上安裝Oracle10g報(bào)ins_emdb.mk錯誤處理方法
oracle安裝過程報(bào)ins_emdb.mk錯誤,此時(shí)繼續(xù)點(diǎn)擊“continue”即可,待Oracle完成安裝后,再手工執(zhí)行相應(yīng)腳本完成鏈接即可2014-09-09
Oracle表的分類以及相關(guān)參數(shù)的詳解
本篇文章是對Oracle中表的分類以及相關(guān)參數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
oracle中對JSON數(shù)據(jù)處理的詳細(xì)指南
很多人對JSON不陌生,JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,下面這篇文章主要給大家介紹了關(guān)于oracle中對JSON數(shù)據(jù)處理的詳細(xì)指南,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
Oracle數(shù)據(jù)泵的導(dǎo)入與導(dǎo)出實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于Oracle數(shù)據(jù)泵的導(dǎo)入與導(dǎo)出的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
PLSQL配置遠(yuǎn)程Oracle數(shù)據(jù)庫連接的示例代碼
這篇文章主要介紹了PLSQL配置遠(yuǎn)程Oracle數(shù)據(jù)庫連接的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Oracle使用RMAN備份數(shù)據(jù)庫的流程步驟
使用 RMAN(Recovery Manager)備份 Oracle 數(shù)據(jù)庫是確保數(shù)據(jù)安全和可恢復(fù)性的關(guān)鍵步驟,下面是詳細(xì)的指導(dǎo)和代碼示例,展示如何使用 RMAN 進(jìn)行數(shù)據(jù)庫備份,感興趣的小伙伴跟著小編一起來看看吧2024-09-09

