好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

oracletrigger代码

sql 代码 --[6]// Oracle Trigger -- 实例 1------------------------ -- 创建触发器,当用户对 test 表执行 DML 语句时,将相关信息记录到日志表 -- 创建测试表 CREATE TABLE test ( t_id NUMBER(4), t_name VARCHAR2(20), t_age NUMBER(2), t_sex CHAR );

sql 代码

--[6]// Oracle Trigger -- 实例 1------------------------ -- 创建触发器,当用户对 test 表执行 DML 语句时,将相关信息记录到日志表 -- 创建测试表 CREATE TABLE test ( t_id NUMBER(4), t_name VARCHAR2(20), t_age NUMBER(2), t_sex CHAR ); -- 创建记录测试表 CREATE TABLE test_log ( l_user VARCHAR2(15), l_type VARCHAR2(15), l_date VARCHAR2(30) ); -- 创建触发器 CREATE OR REPLACE TRIGGER test_trigger AFTER DELETE OR INSERT OR UPDATE ON test DECLARE v_type test_log.l_type%TYPE; BEGIN IF INSERTING THEN --INSERT 触发 v_type := 'INSERT'; DBMS_OUTPUT.PUT_LINE(' 记录已经成功插入,并已记录到日志 '); ELSIF UPDATING THEN --UPDATE 触发 v_type := 'UPDATE'; DBMS_OUTPUT.PUT_LINE(' 记录已经成功更新,并已记录到日志 '); ELSIF DELETING THEN v_type := 'DELETE'; DBMS_OUTPUT.PUT_LINE(' 记录已经成功删除,并已记录到日志 '); END IF; INSERT INTO test_log VALUES(user,v_type, TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss')); END; / -- 下面我们来分别执行 DML 语句 INSERT INTO test VALUES(101,'zhao',22,'M'); UPDATE test SET t_age = 30 WHERE t_id = 101; DELETE test WHERE t_id = 101; -- 然后查看效果 SELECT * FROM test; SELECT * FROM test_log; -- 实例 2------------------------ -- 创建触发器,它将映射 emp 表中每个部门的总人数和总工资 -- 创建映射表 CREATE TABLE dept_sal AS SELECT deptno,COUNT(empno) AS total_emp,SUM(sal) AS total_sal FROM emp GROUP BY deptno; DESC dept_sal; -- 创建触发器 CREATE OR REPLACE TRIGGER emp_info AFTER INSERT OR UPDATE OR DELETE ON emp DECLARE CURSOR cur_emp IS SELECT deptno,COUNT(empno) AS total_emp,SUM(sal) AS total_sal FROM emp GROUP BY deptno; BEGIN DELETE dept_sal; -- 触发时首先删除映射表信息 FOR v_emp IN cur_emp LOOP --DBMS_OUTPUT.PUT_LINE(v_emp.deptno || v_emp.total_emp || v_emp.total_sal); -- 插入数据 INSERT INTO dept_sal VALUES(v_emp.deptno,v_emp.total_emp,v_emp.total_sal); END LOOP ; END; / -- 对 emp 表进行 DML 操作 INSERT INTO emp(empno,deptno,sal) VALUES('123','10',10000); SELECT * FROM dept_sal; DELETE EMP WHERE empno=123; SELECT * FROM dept_sal; -- 实例 3------------------------ -- 创建触发器,它记录表的删除数据 -- 创建表 CREATE TABLE employee ( id VARCHAR2(4) NOT NULL, name VARCHAR2(15) NOT NULL, age NUMBER(2) NOT NULL, sex CHAR NOT NULL ); DESC employee; -- 插入数据 INSERT INTO employee VALUES('e101','zhao',23,'M'); INSERT INTO employee VALUES('e102','jian',21,'F'); -- 创建记录表 CREATE TABLE old_employee AS SELECT * FROM employee; DESC old_employee; -- 创建触发器 CREATE OR REPLACE TRIGGER tig_old_emp AFTER DELETE ON employee -- FOR EACH ROW -- 语句级触发,即每一行触发一次 BEGIN INSERT INTO old_employee VALUES(:old.id,:old.name,:old.age,:old.sex); --:old 代表旧值 END; / -- 下面进行测试 DELETE employee; SELECT * FROM old_employee; -- 实例 4------------------------ -- 创建触发器,利用视图插入数据 -- 创建表 CREATE TABLE tab1 (tid NUMBER(4) PRIMARY KEY,tname VARCHAR2(20),tage NUMBER(2)); CREATE TABLE tab2 (tid NUMBER(4),ttel VARCHAR2(15),tadr VARCHAR2(30)); -- 插入数据 INSERT INTO tab1 VALUES(101,'zhao',22); INSERT INTO tab1 VALUES(102,'yang',20); INSERT INTO tab2 VALUES(101,'13761512841','AnHuiSuZhou'); INSERT INTO tab2 VALUES(102,'13563258514','AnHuiSuZhou'); -- 创建视图连接两张表 CREATE VIEW tab_view AS SELECT tab1.tid,tname,ttel,tadr FROM tab1,tab2 WHERE tab1.tid = tab2.tid; -- 创建触发器 CREATE OR REPLACE TRIGGER tab_trigger INSTEAD OF INSERT ON tab_view BEGIN INSERT INTO tab1(tid,tname) VALUES(:new.tid,:new.tname); INSERT INTO tab2(ttel,tadr) VALUES(:new.ttel,:new.tadr); END; / -- 现在就可以利用视图插入数据 INSERT INTO tab_view VALUES(105,'zhaoyang','13886681288',' beijing '); -- 查看效果 SELECT * FROM tab_view; -- 实例 5------------------------ -- 创建触发器,比较 emp 表中更新的工资 CREATE OR REPLACE TRIGGER sal_emp BEFORE UPDATE ON emp FOR EACH ROW BEGIN IF :OLD.sal > :NEW.sal THEN DBMS_OUTPUT.PUT_LINE(' 工资减少 '); ELSIF :OLD.sal DBMS_OUTPUT.PUT_LINE(' 工资增加 '); ELSE DBMS_OUTPUT.PUT_LINE(' 工资未作任何变动 '); END IF; DBMS_OUTPUT.PUT_LINE(' 更新前工资 : ' || :OLD.sal); DBMS_OUTPUT.PUT_LINE(' 更新后工资 : ' || :NEW.sal); END; / -- 执行 UPDATE 查看效果 UPDATE emp SET sal = 3000 WHERE empno = '7788'; -- 实例 6------------------------ -- 创建触发器,将操作 CREATE 、 DROP 存储在 log_info 表 -- 创建表 CREATE TABLE log_info ( manager_user VARCHAR2(15), manager_date VARCHAR2(15), manager_type VARCHAR2(15), obj_name VARCHAR2(15), obj_type VARCHAR2(15) ); -- 创建触发器 CREATE OR REPLACE TRIGGER trig_log_info AFTER CREATE OR DROP ON SCHEMA BEGIN INSERT INTO log_info VALUES(USER,SYSDATE,SYS.DICTIONARY_OBJ_NAME,SYS.DICTIONARY_OBJ_OWNER, SYS.DICTIONARY_OBJ_TYPE); END; / -- 测试语句 CREATE TABLE a(id NUMBER); CREATE TYPE aa AS OBJECT(id NUMBER); / DROP TABLE a; DROP TYPE aa; -- 查看效果 SELECT * FROM log_info; -- 相关数据字典 -----------------------------------------------------// SELECT * FROM USER_TRIGGERS; SELECT * FROM ALL_TRIGGERS; SELECT * FROM DBA_TRIGGERS; -- 必须以 DBA 身份登陆才能使用此数据字典 -- 启用和禁用 ALTER TRIGGER trigger_name DISABLE; ALTER TRIGGER trigger_name ENABLE; ------------------------------------------------------------------------------------------End//


关于在 oracle trigger (insert )事件中调用存储过程的问题

最近用 ORACLE 触发器写了点东西 , 不过 , 确发现 ORA-04092 、 ora-06512  等错误。怎么办?

最初,我也被弄得手忙脚乱。

于是,我查看  ORA-04092  提示的错误信息,是ROLLBACK和COMMIT 命令不能出现在触发器中。

于是,开始解决问题。发现, 当在触发器里加入事务性操作时,会有如下错误: ORA-04092 cannot string in a trigger. 解决办法,在触发器里加入声明 PRAGMA AUTONOMOUS_TRANSACTION ,好了,不在弹出错误信息。

可是,我通过触发器调用存储过程,却发现存储过程执行后,数据没任何变化(我的存储过程是执行一次,删除一次中间表数据。)。难道是我的存储过程出了问题?单步调试,没任何问题。执行结果正确。

通过多次测试,发现原来是触发触发器的时候(触发事件为  insert   after )由于没有提交(COMMIT)数据。在中间表中就查不到任何数据。处理方法,

第一步、新建一个中间表,做为触发器触发事件发生的中间表。

第二步、在中间表插入数据,提交。

第三步、在第一步新建的中间表中插入数据,提交执行成功。

第四步、检查结果,正常。


能否在表的触发器中当一记录变化修改另一记录

SQL> create or replace trigger addnum
2 before update on test1.test1
3 for each row
4 begin
5 update test1 set group1=(:new.group1+1) where group1=2;
6 end;
7 /

触发器已创建

已用时间 : 00: 00: 00.00
SQL> update test1 set group1=7 where group1=1;
update test1 set group1=7 where group1=1
*
ERROR 位于第 1 行 :
ORA-04091: 表 TEST1.TEST1 发生了变化,触发器 / 函数不能读
ORA-06512: 在 "TEST1.ADDNUM", line 2
ORA-04088: 触发器 'TEST1.ADDNUM' 执行过程中出错


这样是肯定不行的,因为触发器会引起死循环。用表层触发器,但表层是不能用 :new 或 :old


SQL> create or replace procedure test3(i number,m number)
2 as
3 a number;
4 str char(1000);
5 begin
6 update test1 set group1=i where group1=m;
7 execute immediate 'COMMIT';
8 a:=i;
9 for a in i..m loop
10 update test1 set group1=i+1 where group1=i;
11 execute immediate 'COMMIT';
12 end loop;
13 end test3;
14 /

过程已创建。

已用时间 : 00: 00: 00.00
SQL> exec test3(2,4);
BEGIN test3(2,4); END;

*
ERROR 位于第 1 行 :
ORA-04091: 表 TEST1.TEST1 发生了变化,触发器 / 函数不能读
ORA-06512: 在 "TEST1.ADDNUM", line 2
ORA-04088: 触发器 'TEST1.ADDNUM' 执行过程中出错
ORA-06512: 在 "TEST1.TEST3", line 6
ORA-06512: 在 line 1



1 、使用视图或者临时表

You can do:
1. Rename your table with another name;
2. Create a view for select * from the table with the original name of the table;
3. Create a instead of trigger on the view, in the view you can access and update yur base

table.


Example of instead of trigger for this case:

[ Code Start ]
create table t1(
id number(6) primary key
,pid number(6)
,value number(15,2)
,f1 varchar2(10)
,f2 varchar2(20)
);


create or replace view t1_v as select * from t1;

create or replace trigger bug_t1_v
instead of update on t1_v
for each row
declare
procedure update_parents(i_id in number, i_value in number);
procedure update_parents(i_id in number, i_value in number) is
begin
declare
l_pid t1.pid%type;
begin
select pid into l_pid
from t1
where id = i_id;
if l_pid 0 then
update t1 set value = nvl(value,0) + nvl(i_value,0)
where id = l_pid;
update_parents(l_pid, i_value);
end if;
exception
when no_data_found then
null;
end;
end update_parents;
begin
--
-- Update Value Field for current record and Parent records
--
if nvl(:new.value,0) - nvl(:old.value,0) 0 then
update t1 set value = value + nvl(:new.value,0) - nvl(:old.value,0)
where id = :new.id;
update_parents(:new.id, nvl(:new.value,0) - nvl(:old.value,0));
end if;
--
-- Update Others Fields
--
update t1 set f1 = :new.f1
,f2 = :new.f2
where id = :new.id;
end;

--
-- Testing
--
-- With this view: t1_v
--
begin
for i in 1..50 loop
Insert into t1_v values(i, i-1, 0, '', '');
end loop;
end;
/

delete from t1_v;

begin
for i in 1..50 loop
Insert into t1_v values(i, i-1, 0, '', '');
end loop;
end;
/

update t1_v set f1 = 'TEST' where id = 49;


update t1_v set value = value + 5 , f1 = 'AA', F2 = 'BB'
where id = 50;


[ Code End ]

使用临时表

11:04:36 SQL> CREATE GLOBAL TEMPORARY TABLE Tmp(
11:04:39 2 rid varchar2(20))ON COMMIT DELETE ROWS;

表已创建。

已用时间 : 00: 00: 00.16
11:07:30 SQL> create or replace trigger trg_tb
11:07:36 2 after insert on tb
11:07:36 3 for each row
11:07:36 4 begin
11:07:36 5 if :new.col2='laji' then
11:07:36 6 insert into tmp values(:new.rowid);
11:07:36 7 end if;
11:07:36 8 end trg_tb;
11:07:36 9 /

触发器已创建

已用时间 : 00: 00: 00.47
11:07:36 SQL> create or replace trigger trg_tb_del
11:07:44 2 after insert on tb
11:07:46 3 begin
11:07:46 4 delete from tb where exists(select 1 from tmp where rid=tb.rowid);
11:07:46 5 end trg_tb_del;
11:07:46 6 /

触发器已创建

已用时间 : 00: 00: 00.31
11:08:59 SQL> select count(1) from tb;

COUNT(1)
----------
22

已用时间 : 00: 00: 00.00
11:09:08 SQL> insert into tb(col1,col2) values('aaa','laji');

已创建 1 行。

已用时间 : 00: 00: 00.00
11:09:12 SQL> select count(1) from tb;

COUNT(1)
----------
22

已用时间 : 00: 00: 00.16
11:09:14 SQL>

From Metalink

Problem Description -------------------
Oracle does not allow you to read a mutating table in a row trigger because if you can read it,

the information may be incorrect (not read consistent). If you attempt this, the following error

is returned:
ORA-04091
Table %s.%s is mutating, trigger/function may not see it
However, you can perform this operation in a statement trigger.
One way to handle this situation is to use a package PL/SQL table to store ROWIDs of updated

records in a row trigger, and reprocess the updated
records in a statement trigger.
Below is an example.

Important Note --------------
Note that there are concurrency issues with this if more than one session tries to perform

operations simultaneously.
This is not intended as a total solution, but as the framework to help show one option.
Example Workaround ------------------
[code:1:50147eb56b]
create or replace package emp_pkg as
type
emp_tab_type is table of rowid index by binary_integer;
emp_tab
emp_tab_type;
emp_index binary_integer;
end emp_pkg;
/
create or replace trigger emp_bef_stm_all
before insert or update or delete on emp
begin
/*
Remember to reset the pl/sql table before each statement
*/
emp_pkg.emp_index := 0;
end;
/
create or replace trigger emp_aft_row_all
after insert or update or delete on emp
for each row
begin
/*
Store the rowid of updated record into global pl/sql table
*/
emp_pkg.emp_index := emp_pkg.emp_index + 1;
emp_pkg.emp_tab(emp_pkg.emp_index) := :new.rowid;
end;
/


create or replace trigger emp_aft_stm_all
after
insert or update or delete on emp
begin
for i in 1 .. emp_pkg.emp_index loop
/*

Re-process the updated records.
There is no restriction here.
*/
dbms_output.put_line(emp_pkg.emp_tab(i));
end loop;
emp_pkg.emp_index := 0;
end;
/
怎么样把提交的数据通过触发器进行验证,如果不合条件,直接删除?

楼主 andywzw () 2004-09-30 11:04:40 在 Oracle / 开发 提问

在应用程序中,有些数据是垃圾数据,现在程序在前段提交的时候没有验证机制,补做代价比较大,我现在想能不能在后台 oracle 通过触发器,对插入动作进行验证,如果发现垃圾数据,直接删除,这样比做存储过程进行定时监控要减少系统资源的占用,但是我不知道如何实现,请高手指教! 问题点数: 100 、回复次数: 32 Top

1 楼 drabit ( square ) 回复于 2004-09-30 11:14:23 得分 0

这样做违反事务的一致性要求, oracle 不会提供这种手段的。一次插入的数据要么都插入,要么都不插入。 Top

2 楼 bluelamb ( bluelamb ) 回复于 2004-09-30 11:18:48 得分 0

只能够在提交前验证 Top

3 楼 bzszp ( SongZip ) 回复于 2004-09-30 11:19:44 得分 100

使用临时表

11:04:36 SQL> CREATE GLOBAL TEMPORARY TABLE Tmp(
11:04:39 2 rid varchar2(20))ON COMMIT DELETE ROWS;

表已创建。

已用时间 : 00: 00: 00.16
11:07:30 SQL> create or replace trigger trg_tb
11:07:36 2 after insert on tb
11:07:36 3 for each row
11:07:36 4 begin
11:07:36 5 if :new.col2='laji' then
11:07:36 6 insert into tmp values(:new.rowid);
11:07:36 7 end if;
11:07:36 8 end trg_tb;
11:07:36 9 /

触发器已创建

已用时间 : 00: 00: 00.47
11:07:36 SQL> create or replace trigger trg_tb_del
11:07:44 2 after insert on tb
11:07:46 3 begin
11:07:46 4 delete from tb where exists(select 1 from tmp where rid=tb.rowid);
11:07:46 5 end trg_tb_del;
11:07:46 6 /

触发器已创建

已用时间 : 00: 00: 00.31
11:08:59 SQL> select count(1) from tb;

COUNT(1)
----------
22

已用时间 : 00: 00: 00.00
11:09:08 SQL> insert into tb(col1,col2) values('aaa','laji');

已创建 1 行。

已用时间 : 00: 00: 00.00
11:09:12 SQL> select count(1) from tb;

COUNT(1)
----------
22

已用时间 : 00: 00: 00.16
11:09:14 SQL>

说明刚才插入的数据已经被删除掉了。 Top

4 楼 andywzw () 回复于 2004-09-30 11:20:15 得分 0

实际上我的想法是这样的,先让它插入目标表,同时触发检查这个刚才插入的语句是否符合条件,如果不符合就从目标表中直接删除,如果符合,就不做任何操作。 Top

5 楼 bzszp ( SongZip ) 回复于 2004-09-30 11:21:37 得分 0

通过一个行级触发器 + 一个表级触发器 + 临时表解决。 Top

6 楼 andywzw () 回复于 2004-09-30 11:25:09 得分 0

那我不用再改写前台的应用程序了吗?前台的插入是通过 java 实现的,临时表是否影响正是数据的插入? Top

7 楼 andywzw () 回复于 2004-09-30 11:28:35 得分 0

bzszp(SongZip) 的方案都是很专业的,我太佩服了!我做个实验看结果! Top

8 楼 bzszp ( SongZip ) 回复于 2004-09-30 11:31:19 得分 0

不会的,用 ON COMMIT DELETE ROWS; 方式创建临时表,在会话
commit 以后 oracle 自动清空数据。

Top

9 楼 andywzw () 回复于 2004-09-30 11:38:26 得分 0

对了,你的临时表只有一个字段啊,能满足我对多个字段的验证吗? Top

10 楼 bzszp ( SongZip ) 回复于 2004-09-30 11:41:33 得分 0

没有问题,这个是存放的 rowid ,对于每一行数据都是唯一的。
判断是在行级触发器内部判断,如果是垃圾数据
纪录 :new.rowid 到临时表
在表级触发器里面集中进行删除。 Top

11 楼 andywzw () 回复于 2004-09-30 11:44:18 得分 0

我觉得这样的方式比我们昨天讨论的解决问题的方案更好吧。这样可以避免不断的执行存储过程导致系统性能有影响。 Top

12 楼 drabit ( square ) 回复于 2004-09-30 12:10:08 得分 0

study ! Top

13 楼 fightintokyo () 回复于 2004-09-30 13:11:24 得分 0

bzszp(SongZip) , good !

请教一个初级的问题。上面的解决方案中,行级触发器会确保在表级触发器前被触发么?(对触发器不太了解) Top

14 楼 zhaokeke2004 (男人 · 海洋) 回复于 2004-09-30 13:27:06 得分 0

学习 Top

15 楼 bzszp ( SongZip ) 回复于 2004-09-30 13:34:32 得分 0

to : fightintokyo( 黑龙 )
是的

性能方面应该会好一些吧。
毕竟直接通过 rowid 进行删除,而且是在 commit 之前就删除了
这样那些不需要的数据就没有写回数据文件。 Top

16 楼 andywzw () 回复于 2004-09-30 13:34:53 得分 0

bzszp(SongZip) ,请把你的 tb 表, desc tb 给我看,我怎么做不下去了! Top

17 楼 andywzw () 回复于 2004-09-30 13:39:25 得分 0

bzszp(SongZip) ,是个专家级的人物,解决问题准确,耐心,细致,大家向他致敬!!! Top

18 楼 fightintokyo () 回复于 2004-09-30 13:56:51 得分 0

谢谢 bzszp(SongZip) 。

查了一下资料,果然触发器是按照以下顺序执行的。
1. 执行 before 表级触发器。
2. 以受影响的行进行循环。
a. 执行 before 行级触发器。( commit 为止该行被 lock )
b. 执行 after 行级触发器。
3. 目标表定义的整合性 check
4. 执行 after 表级触发器。

再请教一个问题。
为什么不在行级触发器中直接把不符合条件的数据 delete 了呢?
这样就不需要临时表和行级触发器了亚。 Top

19 楼 andywzw () 回复于 2004-09-30 14:00:30 得分 0

bzszp(SongZip) ,请把你的 tb 表, desc tb 给我看,我怎么做不下去了! Top

20 楼 bzszp ( SongZip ) 回复于 2004-09-30 14:01:30 得分 0

这样会有问题的,行级触发器对于正在处理的表数据有操作限制。 Top

21 楼 bzszp ( SongZip ) 回复于 2004-09-30 14:01:52 得分 0

13:50:23 SQL> desc tb;
名称 空 ? 类型
----------------------------------------- -------- --------------
COL1 VARCHAR2(10)
COL2 VARCHAR2(30)
COLNEW VARCHAR2(20)

13:52:32 SQL> Top

22 楼 andywzw () 回复于 2004-09-30 14:17:20 得分 0

bzszp(SongZip) 这办法绝对很棒,但是问题是
create or replace trigger trg_tb
after insert on tb for each row
begin
if :new.col2='laji' then
insert into tmp values(:new.rowid);
end if;
end trg_tb;
/
这个里面的你现在指定了 col2, 我要指定多列是不是用
if :new.col2='laji' or :new.col1='xxx' or :new.coln='nnn' then
另外,这里的 = 后面的值是唯一的有局限性,我怎么从一个表,例如 bad_word 里面获得这些值? Top

23 楼 andywzw () 回复于 2004-09-30 14:23:43 得分 0

SQL> desc bad_word
名称 空 ? 类型
----------------------------------------- -------- -------------
ID NUMBER(10)
KEY_WORD VARCHAR2(60) Top

24 楼 bzszp ( SongZip ) 回复于 2004-09-30 14:27:22 得分 0

用 select 判断 , 另外声明一个 v_num number 的变量。
select count(*) into v_num from bad_word
where bad_word.colname=:new.col1;
if v_num>0 then -- 属于包含垃圾信息的行
...
end if; Top

25 楼 bzszp ( SongZip ) 回复于 2004-09-30 14:28:25 得分 0

select count(*) into v_num from bad_word
where key_word=:new.col1; Top

26 楼 andywzw () 回复于 2004-09-30 14:58:01 得分 0

不好意思,我不知道怎么申明 v_num 这个变量 :) Top

27 楼 bzszp ( SongZip ) 回复于 2004-09-30 15:02:09 得分 0

如:
create or replace trigger trg_tb
after insert on tb for each row
declare -- 声明变量开始
v_num number; -- 声明 number 类型的变量 v_num
begin
...
Top

28 楼 andywzw () 回复于 2004-09-30 15:23:44 得分 0

bzszp(SongZip) 我试验成功了!再问一下您,如果这种办法用于留言版后台过滤程序是不是很有价值的?比在前台更加主动,减少维护量。 Top

29 楼 bzszp ( SongZip ) 回复于 2004-09-30 15:28:50 得分 0

减少了前台的工作量
但是增加了后台的工作量
这个根据实际情况来定吧。 Top

30 楼 andywzw () 回复于 2004-09-30 16:32:34 得分 0

谢谢,结分,祝 bzszp(SongZip) 及其各位国庆节愉快! Top

31 楼 andywzw () 回复于 2004-09-30 18:13:13 得分 0

create or replace trigger TRG_LEAVE_WORD
after insert on LEAVE_WORD for each row
declare
v_num number;
begin
select count(*) into v_num from bad_word
where key_word like '%'||:new.TITLE||'%' or key_word like '%'||:new.CONTENT||'%';
if v_num>0 then
insert into tmp values(:new.rowid);
end if;
end TRG_LEAVE_WORD;
/

这个触发器还是有问题的,过滤了 CONTENT 但不能过滤 TITLE ,如何解决,难道我的 or 条件有问题? Top

32 楼 andywzw () 回复于 2004-10-01 02:02:28 得分 0

我找到解决的办法了,改写成如下样子完全可以使用:
create or replace trigger TRG_LEAVE_WORD
after insert on LEAVE_WORD for each row
declare
v_num number;
begin
select count(*) into v_num from BAD_WORD
where instr(:new.TITLE,KEY_WORD)>0 or instr(:new.CONTENT,KEY_WORD)>0;
if v_num>0 then
insert into tmp values(:new.rowid);
end if;
end TRG_LEAVE_WORD;

查看更多关于oracletrigger代码的详细内容...

  阅读:50次