在触发器里我要实现这个功能:在触发器T表时,有事件要发生就是要把这个金额大于30万情况下插入数据 而其中的红色‘值’是要在触发时的一个id,我就想要这个值如何实现 Create or replace trigger triggeraccount_secure after insert or update on T for each row declareIF NOT EXISTS 'test' create table test(flag number) ENDIF begin if(SELECT sum(金额) FROM T group by ID HAVING ID=值 )>3000000 insert into test(flag)values(1) else insert into test(flag)values(0) end if end end triggeraccount_secure ;
我的触发器代码如下:create or replace trigger triggeraccount_secure after insert or update on voucherdetail for each row declare IF NOT EXISTS (test) create table test(flag number,ID number) ENDIF Pragma autonomous_transaction; begin if(SELECT sum(T.DBLAMOUNT) DBLAMOUNT FROM VOUCHERDETAIL T LEFT JOIN Account B ON T.LNGACCOUNTID=B.LNGACCOUNTID where B.STRACCOUNTCODE like '1002%' group by lngVoucherID having lngVoucherID=:new.lngVoucherID)>3000000 insert into test(flag)values(1,:new.lngVoucherID) else insert into test(flag)values(0,:new.lngVoucherID) end if end triggeraccount_secure ; 编译出现错误如下: Compilation errors for TRIGGER GADATA0016.TRIGGERACCOUNT_SECUREError: PLS-00103: 出现符号 "IF"在需要下列之一时: begin function package pragma procedure subtype type use <an identifier> <a double-quoted delimited-identifier> form current cursor 符号 "begin" 被替换为 "IF" 后继续。 Line: 5 Text: IF NOT EXISTS (test)Error: PLS-00103: 出现符号 "TEST"在需要下列之一时: ( select Line: 5 Text: IF NOT EXISTS (test)
IF NOT EXISTS (test) create table test(flag number,ID number) ENDIF这种写法 是mysql的,oracle不支持。
你这里需要在trigger里建表,这个不推荐使用,对于ddl语句来说,会破坏原本事务的完整性,ddl执行的时候会提交已有的事务,所以事务性已经破坏,在procedure和trigger要慎用。及时实在要使用,不能像你这样使用,需要通过动态sql execute immediate 'create table test(id int, name varchar(200))'来执行本来在procedure和trigger的代码段里,加入ddl语句是通不过语法检查的,估计就是是考虑到事务性不完整带来的危险,但是我们的程序员太厉害了,通过execute immediate提供的动态sql实现此过程
如果可以先建好表,就最好先建好表先。关于自治事务,贴一个我自己写的sample里自己对着来表结构 SQL> desc test_3; 名称 是否为空? 类型 ----------------------------------------- -------- ------------------- IDA NUMBER(38) IDB NUMBER(38) NAME VARCHAR2(100) trigger的samplecreate or replace trigger tri_test_3_insert after insert or update on test_3 for each row declare a exception; --pragma exception_init(a,-1476); v number; pragma autonomous_transaction; begin select count(1) into v from test_3; dbms_output.put_line(v||'---'||:new.name||'---'||:new.ida||'---'||:new.idb); --raise_application_error(-11111, 'error'); commit; Exception When others then ROLLBACK; --raise a; raise; end; /
1 1
2 2
2 3
2 4
3 5id为2的只触发一次
每个唯一的id只触发一次,并且记录起来这个id值作为下一个的查询条件
而其中的红色‘值’是要在触发时的一个id,我就想要这个值如何实现
Create or replace trigger triggeraccount_secure
after insert or update on T
for each row
declareIF NOT EXISTS 'test'
create table test(flag number)
ENDIF
begin
if(SELECT sum(金额)
FROM T
group by ID HAVING ID=值 )>3000000
insert into test(flag)values(1)
else
insert into test(flag)values(0)
end if end
end triggeraccount_secure ;
这里要注意一个问题,在行级trigger是不能对本身的表,进行query和其他的dml的语句的,如果出现这样的情况定义过程为自制事务,在begin上面加上
pragma autonomous_transaction;
after insert or update on voucherdetail
for each row
declare
IF NOT EXISTS (test)
create table test(flag number,ID number)
ENDIF
Pragma autonomous_transaction;
begin
if(SELECT sum(T.DBLAMOUNT) DBLAMOUNT
FROM VOUCHERDETAIL T LEFT JOIN Account B ON
T.LNGACCOUNTID=B.LNGACCOUNTID where B.STRACCOUNTCODE like '1002%'
group by lngVoucherID having lngVoucherID=:new.lngVoucherID)>3000000
insert into test(flag)values(1,:new.lngVoucherID)
else
insert into test(flag)values(0,:new.lngVoucherID)
end if
end triggeraccount_secure ;
编译出现错误如下:
Compilation errors for TRIGGER GADATA0016.TRIGGERACCOUNT_SECUREError: PLS-00103: 出现符号 "IF"在需要下列之一时:
begin function package
pragma procedure subtype type use <an identifier>
<a double-quoted delimited-identifier> form current cursor
符号 "begin" 被替换为 "IF" 后继续。
Line: 5
Text: IF NOT EXISTS (test)Error: PLS-00103: 出现符号 "TEST"在需要下列之一时:
( select
Line: 5
Text: IF NOT EXISTS (test)
create table test(flag number,ID number)
ENDIF这种写法 是mysql的,oracle不支持。
SQL> desc test_3;
名称 是否为空? 类型
----------------------------------------- -------- ------------------- IDA NUMBER(38)
IDB NUMBER(38)
NAME VARCHAR2(100)
trigger的samplecreate or replace trigger tri_test_3_insert
after insert or update on test_3
for each row
declare
a exception;
--pragma exception_init(a,-1476);
v number;
pragma autonomous_transaction;
begin
select count(1) into v from test_3;
dbms_output.put_line(v||'---'||:new.name||'---'||:new.ida||'---'||:new.idb);
--raise_application_error(-11111, 'error');
commit;
Exception
When others
then
ROLLBACK;
--raise a;
raise;
end;
/
对着这个sample改成你自己的。