服务器 频道

在DB2中创建第一个触发器

  8. 触发器触发于每行

 

  引起触发事件的语句可能会同时影响数据库中的多行。"For each Row" 选项意味着触发器将在每一行被修改时激活。另一方面,"For each statement" 选项("before" 型触发器是不允许的)则意味着触发器定义的操作只在调用一次 SQL 语句后执行一次。

  可以点击 Show SQL按钮来看看底层的 SQL 语句到目前为止是什么样子:

  图 9. Show SQL 框

 

  构建触发动作

  现在该创建触发动作了。我们的业务规则是支票帐户的余额必须低于 0 才能激活该触发器。也就是说,我们需要指定 search-condition 为 NEWROW.CHECKINGBALANCE<0 。我们之所以指定 NEWROW.CHECKINGBALANCE 是因为需要分析在 update 操作之后支票帐户的余额将会是多少。

  创建触发器主体

现在我们将要在 Triggered Action 文本区域中替换 triggered-SQL-statement (参见下面)。

  图 10. 创建触发器语句

 

  用来替换的代码如下:

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;

  让我们一句一句地仔细研究一下这段代码。在触发器主体中,可以声明将要在主体中使用的变量。我们使用下面这行代码来声明变量: decimal(7,2)declare overage decimal (7,2) ; 这样就定义了一个类型为 decimal(7,2) 名为 overage 的变量。

  下一步我们将 overage 变量的值设置为 (NEWROW.CHECKINGBALANCE*-1) ;

  我们将使用该算式计算出我们想要从支票帐户取出的超额(overage)的数目。指定 NEWROW.CHECKINGBALANCE 是因为我们需要分析支票帐户的余额在 update 操作发生后是多少。

  set overage = (NEWROW.CHECKINGBALANCE*-1);

  发出错误条件信号

  如果违反了您在触发器中定义的业务规则,就可以使用 SIGNAL 语句来抛出一个错误条件信号。在我们的例子中,不允许有人拥有的支票帐户余额为负数。如果有人想要将支票帐户的余额列更新为一个负数,我们就可以试着看看在储蓄帐户中是否有足够多的钱来补偿这个负数。如果没有,那么就可以发出一条 SQL 状态为 ''70001'' 的信息 "''Overdraft Protection Unsuccessful"。

  认识到包含 SIGNAL 语句的效果是很重要的。SIGNAL 语句回滚由触发语句(也就是我们的 update 语句)尝试的更改。SIGNAL 语句也将回滚在触发器内发生的更改。此外,假设我们是使用 Java™ 应用程序来与数据库进行交互的,并且试图执行一次会触发我们的触发器并违反业务规则的 update 操作。Java 应用程序将接受我们所指定的 SQLSTATE 以及值为 -438 的 SQLCODE。在这行中我们使用 SIGNAL SQLSTATE 属性:

if overage>OLDROW.SAVINGBALANCE then SIGNAL SQLSTATE ''70001'' 
(''Overdraft Protection Unsuccessful'');

  该行说明,如果我们的 overage 比储蓄帐户的余额数目还要大,那么就需要抛出一个危险信号。

  转帐

如果储蓄帐户的余额数目足够补偿超出的数目,这时就会发生转帐。如果满足这种条件,我们将对新行作两处修改:

  1. 修改 "new row" 的 savingbalance 列,将其减去 overage 以促成透支转帐。
  2. 将支票帐户的余额设置为 0。我们使用下面的代码来完成:

else set newrow.savingbalance = oldrow.savingbalance-overage,             
newrow.checkingbalance = 0; end if;

  最终结果

可以再次通过 Show SQL按钮来看看最后的结果:

  图 11.显示 SQL

 

  在点击 Close之后,您将看到 OVERDRAFT 触发器已经创建好了:

  图 12. 创建 OVERDRAFT 触发器

 

  测试

可以通过一个 update 语句来进行测试。打开命令行编写下面的语句:

db2=> 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)。下面的查询验证了该结果:

  图 13. 查询

 

  尾声

    您已经在一个假想的业务场景中创建了一个 DB2 触发器。触发器是 DB2 数据库的一个非常强大的特性,您可以使用它将业务逻辑分化到关系数据库这边。如果考虑到有多个应用程序都将与同一个数据库进行交互,您就会发现这种分化是非常强大的。在一个大型企业中,您可能多次遇到过这样的情况,即不知道要创建的是怎样一个将与数据库交互的应用程序。与其只是希望这些应用程序遵守被认为是您的组织机构的戒律的业务规则,还不如使用触发器作为您工具箱中的一种工具,以确保现在和将来与数据库进行交互的所有的应用程序强制遵守这些业务规则。一个触发器只能关联一个表,而不能关联一个视图。您也许可以考虑使用 INSTEAD OF 触发器来与视图交互。

0
相关文章