Oracle创建触发器详解及例子

触发器详解
1。触发器与触发该触发器的SQL语句同属于一个事务,触发器不允许发出任何事务控制语句,如 commit、rollback、savepoint或者set transaction,它只能随着外部事务的提交、回滚而提交、回滚。(但在oracle8i 以及更高的版本中,你可以创建作为自治事务而执行的触发器,在这种情况下,触发器可以做提交或回滚操作,而与触发该触发器的外部SQL所在的事务无关)
2。与上面相同,在触发器内调用的所有过程、函数也都不能有事务控制语句,除非它们被声明为自治事务( declare pragma autonomous_transaction;)。
1.创建表结构
CREATE TABLE TLK_P_NEWS_MDS(
ID VARCHAR2(1000 BYTE) NOT NULL,
NEWSID VARCHAR2(1000 BYTE),
MANDATESCOPE VARCHAR2(1000 BYTE),
MANDATETYPE VARCHAR2(2 BYTE)
);
Create unique Index NEWS_MDS_Index1 On TLK_P_NEWS_MDS(ID) ;
Create Index NEWS_MDS_Index2 On TLK_P_NEWS_MDS(NEWSID);
Create Index NEWS_MDS_Index3 On TLK_P_NEWS_MDS(MANDATESCOPE);

2.创建触发器
CREATE OR REPLACE TRIGGER tr_p_news AFTER
DELETE OR
INSERT OR
UPDATE ON tlk_p_news FOR EACH row DECLARE integrity_error EXCEPTION;
errno INTEGER;
errmsg CHAR(200);
BEGIN
IF inserting THEN
proc_mandatescope(:new.id,’News’,:new.item_mandatescope);
elsif updating THEN
proc_mandatescope(:old.id,’News’,:new.item_mandatescope);
elsif deleting THEN
proc_mandatescope(:old.id,’News’,NULL);
END IF;
EXCEPTION
WHEN integrity_error THEN
raise_application_error(errno, errmsg);
END;
3.创建存储过程
create or replace PROCEDURE PROC_MANDATESCOPE(
DATAID IN VARCHAR2,
TABLENAME IN VARCHAR2,
MANDATESCOPE IN CLOB )
AS
AV_SPLIT VARCHAR2(2) := ‘;’;
V_MANDATESCOPE CLOB;
V_LENGTH NUMBER;
V_START NUMBER;
V_INDEX NUMBER;
V_STR VARCHAR2(1000);
V_MANDATETYPE VARCHAR2(2);
V_SQL VARCHAR2(1000);–动态sql
BEGIN
V_SQL:=’DELETE FROM TLK_P_’||TABLENAME||’_mds WHERE ‘||TABLENAME||’ID =”’||DATAID||””;
EXECUTE IMMEDIATE(V_SQL);
IF MANDATESCOPE IS NOT NULL THEN
V_MANDATESCOPE := REPLACE(MANDATESCOPE,’,’,’;’);
V_LENGTH := LENGTH(V_MANDATESCOPE);
V_START :=1;
V_INDEX :=0;
V_STR :=”;
IF INSTR(V_MANDATESCOPE ,AV_SPLIT) >0 THEN
WHILE(V_START <= V_LENGTH)
LOOP
V_INDEX := INSTR(V_MANDATESCOPE, AV_SPLIT, V_START);
IF V_INDEX = 0 THEN
V_MANDATETYPE := SUBSTR(V_MANDATESCOPE, V_START,1);
V_STR :=SUBSTR(V_MANDATESCOPE, V_START);
V_START := V_LENGTH + 1;
ELSE
V_MANDATETYPE := SUBSTR(V_MANDATESCOPE, V_START, 1);
V_STR :=SUBSTR(V_MANDATESCOPE, V_START, V_INDEX - V_START);
V_START := V_INDEX + 1;
END IF;
V_SQL:=’INSERT INTO TLK_P_’||TABLENAME||’_mds (ID,’||TABLENAME||’ID,MANDATESCOPE,MANDATETYPE) VALUES(”’||SYS_GUID()||”’,”’||DATAID||”’,”’||V_STR||”’,”’||V_MANDATETYPE||”’)’;
EXECUTE IMMEDIATE(V_SQL);
END LOOP;
ELSE
V_MANDATETYPE := SUBSTR(V_MANDATESCOPE, V_START,1);
V_SQL :=’INSERT INTO TLK_P_’||TABLENAME||’_mds (ID,’||TABLENAME||’ID,MANDATESCOPE,MANDATETYPE) VALUES(”’||SYS_GUID()||”’,”’||DATAID||”’,”’||V_MANDATESCOPE||”’,”’||V_MANDATETYPE||”’)’;
DBMS_OUTPUT.PUT_LINE(‘INPUT1:’||V_SQL ); –監視SQL語句
EXECUTE IMMEDIATE(V_SQL);
END IF;
–提交
END IF;
END PROC_MANDATESCOPE;

猜你喜欢

转载自blog.csdn.net/qq_40112624/article/details/81874976
今日推荐