存储过程,类似于高阶语言的函数或者方法,包含SQL语句序列,是可复用的语句,保存在数据库中,在服务器中执行。特点是复用,提高了效率,安全性。
触发器(Trigger)是数据库中一种特殊的存储过程,它可以在数据表上定义特定的事件(如插入、更新或删除操作)发生时自动执行。触发器的主要作用是实现数据的完整性约束、审计、日志记录等功能。在SQL语言中,触发器的使用非常广泛,它可以帮助我们更好地管理和维护数据库。
触发器的主要特点如下:
触发器数据库对象,当创建一个触发器时必须指定:1> 名称;2> 在其上定义触发器的表;3> 触发器将何时激发;4> 指明触发器执行时应做的动作。其名称必须遵循标识符的命名规则,数据库像存储普通数据那样存储触发器。触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。尽管不能在临时表或系统表上创建触发器,但是触发器可以引用临时表。
触发动作实际上是一系列SQL语句,可以有两种方式:
(1) 对被事件影响的每一行(FOR EACH ROW),每一元组执行触发过程,称为行级触发器。
(2) 对整个事件只执行一次触发过程(FOR EACH STATEMENT),称为语句级触发器。该方式是触发器的默认方式。
触发器主要包括两个方面:指明触发器的触发事件,指明触发器执行的动作。
触发事件包括表中行的插入、删除和修改,即执行 INSERT、DELETE、UPDATE 语句。 在修改操作 (UPDATE)中,还可以指定特定的属性或属性组的修改为触发条件。事件的触发还有两个相关的时间:BEFORE 和 AFTER。BEFORE 触发器是在事件发生之前触发,AFTER 触发器是在事件发生之后触发。创建触发器语句格式如下:
CREATE TRIGGER <触发器名> [{BEFORE|AFTER}]
{[DELETE|INSERT|UPDATE OF[列名清单]]}
ON
[REFERENCING <临时视图名>]
[FOR EACH ROW|FOR EACH STATEMENT]
[WHEN <触发条件>]
BEGIN
<触发动作>
END [触发器名];
参数说明:
示例1. 银行数据库关系模式如下:
Account (Account-no, branch-name, balance)
Loan (Loan-no, branch-name, amount)
Depositor (customer-name, Account-no)
账户关系模式 Account 中的属性 Account-no 表示账号 ,branch-name 表示支行名称,balance 表示余额。贷款关系模式 Loan 中的属性 Loan-no 表示贷款号,branch-name 表示支行名称,amount 表示金额。存款关系模式 Depositor 中的属性 customer-name 表示存款人姓名。SQL-99 创建触发器如下所示:
CREATE TRIGGER overdraft_trigger AFTER UPDATE ON Account
REFERENCING NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.balance < 0
BEGIN ATOMIC
INSERT INTO borrower
(SELECT customer-name,Account-no
FROM Depositor
WHERE nrow.account-no = Depositor.account-no);
INSERT INTO loan VALUES (nrow.account-no,branch-name,-nrow.balance);
UPDATE account SET balance = 0
WHERE account.account-no = nrow.account-no;
END;
When语句指定一个条件nrow.balance<0。仅对满足条件的元组才会执行余下的触发器;BEGIN ATOMIC 子句用来将多行SQL语句集成为一个复合语句,该子句中的两条 INSERT INTO 语句执行了在borrower和loan关系中建立新的贷款业务;UPDATE语句用来将账户余额清零;
示例2. 仓库管理数据库中有如下关系,请创建一个重新订购商品的触发器。
inventory(item,level) :表示某种商品在仓库中的现有量
minlevel(item,level) :表示某种商品在仓库中存有的最小量
reorder(item,amount) :表示某种商品小于最小量的时候要订购的数量
orders(item,amount):表示某种商品被定购的量
CREATE TRIGGER reorder_trigger AFTER UPDATE OF amount on inventory
REFERENCING OLD ROW AS orow,NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.level <= (SELECT level
FROM minlevel
WHERE minlevel.item = orow.item)
AND orow.level > (SELECT level
FROM minlevel
WHERE minlevel.item = orow.item)
BEGIN
INSERT INTO orders
(SELECT item,amount
FROM reorder
WHERE reorder.item = orow.item)
END;
示例3. 若修改某商品的库存时,使得库存值小于或等于其最小库存值,则向采购表插入一条记录,要求采购的数量是该商品最小库存值的两倍再加上10。
CREATE TRIGGER 采购-trigger AFTER UPDATE ON 商品 [AFTER UPDATE OF 库存 ON 商品]
REFERENCING NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.库存<=nrow.最小库存
BEGIN
INSERT INTO 采购(商品号,采购数量)
VALUES(nrow.商品号,nrow.最小库存*2+10)
END;
使用系统命令 ALTER TRIGGER 更改指定的触发器的定义,语法如下:
ALTER TRIGGER <触发器> [{BEFORE|AFTER}] {[DELETE|INSERT|UPDATE OF [列名清单]]}
ON 表名|视图名
AS
BEGIN
SQL STATEMENTS
END;
使用 DROP TRIGGER <触发器>[,…n]
,其中,n 表示可以指定多个触发器的占位符。
触发器是数据库中一种非常重要的功能,它可以帮助我们实现数据的完整性约束、审计、日志记录等功能。通过合理地使用触发器,我们可以提高数据库的性能和数据的一致性,从而更好地管理和维护数据库。然而,触发器的使用也需要谨慎,因为不当的使用可能会导致性能问题和数据不一致的问题。因此,在使用触发器时,我们需要充分了解其原理和使用方法,以确保其能够发挥最大的作用。