建立测试表
test:
CREATE TABLE TEST (
"ID" INTEGER,
"NAME" VARCHAR(20)
)
test01:
create table test01 like test
--2张表test与test01,往test插入数据后,同步往test01记录,创建触发器test01如下:
CREATE or replace TRIGGER test
AFTER INSERT ON test
REFERENCING NEW AS n
FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
INSERT INTO test01(id,name)
VALUES(n.id,n.name);
END
@
参考:http://www.ibm.com/developerworks/cn/data/library/techarticles/0308bhogal/0308bhogal.html
例如,一个银行客户有一个支票帐户(checking account)和一个储蓄帐户(saving account)。当从支票帐户中取款的金额超过了该帐户的余额时,就会发生一次自动的转帐(叫做透支保护),即自动从客户的储蓄帐户转帐过来。当然,这必须符合一定的条件,即储蓄帐户中必须有足够多的钱来补偿透支的金额。
在这张表中,我们将存入客户的支票帐户和储蓄帐户的余额等信息。每个客户通过其社会保险号码来标识。
现在,创建 accttable
表:
create table accttable(
ssn varchar(30) not null primary key,
lastname varchar(30) not null,
firstname varchar(30) not null,
savingbalance decimal(7,2) not null,
checkingbalance decimal(7,2) not null)
现在向所创建的表中加入两条记录:
insert into accttable values('111-11-1111','Bhogal','Kulvir',1500.00,1000);
insert into accttable values('222-22-2222','Guy','Someother',2000.00,4000);
现在该创建触发动作了。我们的业务规则是支票帐户的余额必须低于 0 才能激活该触发器。也就是说,我们需要指定 search-condition 为 NEWROW.CHECKINGBALANCE<0
。我们之所以指定 NEWROW.CHECKINGBALANCE
是因为需要分析在 update 操作之后支票帐户的余额将会是多少。
set overage = (NEWROW.CHECKINGBALANCE*-1);设置成正数进行比较。
1、如果违反了您在触发器中定义的业务规则,就可以使用 SIGNAL 语句来抛出一个错误条件信号。在我们的例子中,不允许有人拥有的支票帐户余额为负数。如果有人想要将支票帐户的余额列更新为一个负数,我们就可以试着看看在储蓄帐户中是否有足够多的钱来补偿这个负数。如果没有,那么就可以发出一条 SQL 状态为 '70001' 的信息 "'Overdraft Protection Unsuccessful"。
2、如果储蓄帐户的余额数目足够补偿超出的数目,这时就会发生转帐。如果满足这种条件,我们将对新行作两处修改:
- 修改 "new row" 的 savingbalance 列,将其减去 overage 以促成透支转帐。
- 将支票帐户的余额设置为 0。我们使用下面的代码来完成:
CREATE OR REPLACE TRIGGER OVERDRAFT
NO CASCADE
BEFORE UPDATE OF CHECKINGBALANCE ON ACCTTABLE REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW MODE DB2SQL
WHEN ( newrow. checkingbalance < 0)
BEGIN ATOMIC
declare overage decimal (7,2);
set overage = (NEWROW.CHECKINGBALANCE*-1);
if overage>OLDROW.SAVINGBALANCE then SIGNAL SQLSTATE '70001'
('Overdraft Protection Unsuccessful');
else
set newrow.savingbalance = oldrow.savingbalance-overage, newrow.checkingbalance = 0;
end if;
END
测试:
update accttable set checkingbalance = -500 where ssn='111-11-1111'
根据我们创建的业务逻辑,这个 update 操作将启动该触发器,由于支票帐户透支,该触发器将从 savingbalance 列取出 500.00 到支票帐户。因此,SSN 为 111-11-1111 的帐户的 checkingbalance 会变成 0.00 而 savingbalance 将变成 1000.00(原来的余额 1500 - 透支的 500)。下面的查询验证了该结果:
select * from accttable where ssn='111-11-1111'
----------------------------------------
111-11-1111 Bhogal Kulvir 1000 0
禁用和启用触发器:
alter trigger <trigger_name> disable;
alter trigger <trigger_name> enable;