葛雪瑞 陈涵
摘要:在信息系统的开发中,和数据库相关的业务逻辑处理应尽量在数据库服务器端完成,这样既利于系统开发效率的提高,也利于数据库中数据安全性的提高。众所周知,银行金融账务管理,重要敏感的数据都存储在数据库中,因此数据处理核心功能也应在服务器上完成,文章给出了利用触发器实现金融账务的存款,取款以及限制日操作金额的方法。
关键词:信息系统开发;数据库业务逻辑处理;开发效率;数据安全性;触发器
中图分类号:G642 文献标识码:A
文章编号:1009-3044(2021)03-0042-02
1引言
关系数据库中允许开发者利用SQL语言编写数据库程序,如存储过程和触发器,以达到将代码集中于数据库后端,简化业务逻辑,提高开发效率,增强数据库安全性的目的。除此之外,存储过程还具有提前编译,运行速度快的特点,而触发器作为一种特殊的存储过程,不但具备存储过程所有特性之外,还具备基于事件驱动的即时响应和自执行能力,常被运用于数据库完整性的维护。[1-2]
2 触发器理论
触发器由若干条SQL 语句组成,可以完成既定的业务规则,特点在于不能像存储过程一样被调用,而是依靠事件被触发。在数据库操作过程中,只要触发事件被满足,触发器即刻被触发,内部的SQL语句就会被执行,因此,开发人员通常会将相关业务逻辑的SQL语句写在触发器体内,以实现程序自动运行,无须人为干预的目的。数据库中利用触发器可以跟踪数据变化,实现复杂规则的约束,同步数据操作,维护数据完整性。
触发器主要分为DDL触发器和DML触发器,前者是数据定义型触发器,当执行CREATE、ALTER、DROP等语句时被触发,用于监控数据库中的重要事件,如库、表结构是否被恶意篡改,这类触发器主要用于保护数据库中对象结构;后者是数据操纵型触发器,当执行INSERT、UPDATE、DELETE语句时被触发,可以保护表中数据,维护表之间数据一致性,是触发器最典型的应用。
在关系型数据库中均能创建触发器,以MSSQL中DML触发器为例,定义规则如下[3]:
CREATE TRIGGER[架构名.]触发器名
ON{表名|视图名}
[WITH ENCRYPTION]
FOR|AFTER|INSTEAD OF操作类型
AS
BEGIN
SQL语句组;
END
GO
其中,操作类型分为:INSERT ,UPDATE,DELETE三种操作。
INSTEAD OF表示当满足触发条件时,跳过对触发表的 INSERT,UPDATE,或 DELETE操作,直接执行触发器定义的SQL语句。
FOR |AFTER 功能相反,当满足触发条件时先对触发表做 INSERT,UPDATE,或 DELETE操作,直接执行触发器定义的SQL语句
3工作原理
在MSSQL中,触发器被触发时会生成两张临时表,INSERTED表和DELETED 表,这两张表中存放对触发表操作的数据行。
若对触发表进行INSERT操作,则插入触发表中新数据行会被插入INSERTED表中;
若对触发表进行DELETE操作,则触发表中被删除的数据行会被插入DELETED表中;
若对触发表进行UPDATE操作,则触发表中被修改前旧的数据行被插入DELETED表中,同时修改后新的数据行被插入INSERTED表中。
所以在编写数据库触发器程序时,可以读取这两张表(INSERTED表和DELETED表中数据只能被读取)中数据,进行规则判断或进一步的业务处理。
需要注意的是:INSERTED表和DELETED 表由系统来维护﹐存在于内存中而不是在数据库中,表的结构与触发表的结构相同。触发器执行完成后﹐这两张表随后被删除。
4 利用触发器实现金融账务管理
实际生活中,我们经常会遇到账务金额操作问题,如在银行存取款后,账号金额应实时更新;操作金额过大时,会给出提醒并拒绝操作;更新密码,系统可以存储新旧密码等等。可以将这些业务逻辑规则对应的SQL语句写在触发器定义中,利用触发器自动被触发的特征,以避免人工操作,提高数据安全性。
已知有账户表 account表和金额交易表dealMoney,账户表中字段有:card_id(账号),card_name(账户名称),card_pass(密码),current_moneny(现有金额)。金额交易表中字段有:id(编号),card_id (账号),交易类型(trans_type),交易金额(trans_money),交易日期(trans_time)。
4.1 存/取款问题级联更新
在实际操作中,每一次操作都会向金额交易表中插入一条数据,交易类型定为存、取款两种,如果是存款,则操作完成后账户表中现有金额=现有金额+交易金额;反之,如果是取款,则操作完成后账户表中現有金额=现有金额-交易金额。
触发器设计如下:
IF EXISTS(SELECT name FROM sysobjects WHERE name='t_dealMoney ' AND type='TR')
DROP TRIGGER t_dealMoney
GO
CREATE TRIGGER t_dealMoney
ON dealMoney
FOR INSERT
AS
DECLARE @card_id char(20),@trans_type varchar(30),@trans_money INT
SELECT @card_id=card_id,@trans_type=trans_type,@trans_money=trans_money
FROM INSERTED
IF(@trans_type='支取')
UPDATEaccount SET current_money=current_money-@trans_money where card_id=@card_id
ELSE
UPDATEaccount SET current_money=current_money+@trans_money where card_id=@card_id
GO
验证触发器:
INSERT INTO dealMoney VALUES('123456789012345','支取',500,getdate());
SELECT * FROM account;
结果证明卡号'123456789012345'的用户对应现有金额字段值减少500.
4.2 限制日操作金额
现实操作中,为保护资金安全,可以对用户每日的操作金额进行限制,如ATM机上日操作限额是10万元,当交易金额超出10万元时,取消本次存款交易,并给出提示“每次交易金额不超过拾万元”。
修改以上触发器t_dealmoney,为其增加限制日操作金额的功能:
ALTERTRIGGER t_dealmoney
ON dealmoney
FOR INSERT
AS
DECLARE @card_id char(20),@trans_type varchar(30),@trans_money INT
SELECT @card_id =card_id,@trans_type =trans_type,@trans_money=trans_money FROMINSERTED
IF(@trans_money >100000)
BEGIN
ROLLBACK TRAN
PRINT '当日交易金额不能大于拾万'
END
ELSE
IF(@trans_type='支取')
UPDATEaccount SET current_money=current_money-@trans_money WHERE card_id=@card_id
ELSE
UPDATE account SET current_money=current_money+@trans_money WHERE card_id=@card_id
GO
验证触发器:
INSERT INTO dealMoney VALUES('123456789012345','支取',150000,getdate());
结果验证:出现'当日交易金额不能大于拾万'信息,程序中止。
5 结束语
大数据时代,数据库使用越来越广泛,在程序开发中合理设计与使用触发器,可以帮助系统开发者和数据库管理者实现诸多复杂业务功能,降低他们的劳动强度[4],同时也能提高系统的数据安全性与完整性。但任何事物都有双面性,触发器的使用尤其如此,它像一把双刃剑,在给人们带来方便的同时,也存在缺点,由于它的隐蔽性,往往在不经意间被触发执行,这也给后期运行维护带来风险与困难,所以,如何在系统开发中合理使用触发器还需进一步研究探讨。
参考文献:
[1]马根峰,王平.触发器在维护关系数据库中数据完整性方面的应用[J].微型计算机与应用,2001(12):56-57.
[2]張玉珍.在多层应用中利用事务处理中的触发器实现数据完整性[J].工业控制计算机,2002,15(8):12-13.
[3] 郑阿奇.SQL Server 实用教程[M].4版,北京:电子工业出版社,2016.
[4] 李虎军.SQL Server 触发器应用探析[J].电脑知识与技术,2016,12(16):13-15.
【通联编辑:王力】