首页 理论教育 SQLServer数据库开发中的高级触发器应用

SQLServer数据库开发中的高级触发器应用

时间:2023-11-02 理论教育 版权反馈
【摘要】:触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。由此可见,触发器可以解决高级形式的业务规则或复杂行为限制以及实现定制记录等一些方面的问题。例如,触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理。总体而言,触发器性能通常比较低。

SQLServer数据库开发中的高级触发器应用

1.概念及作用

触发器是一种特殊类型的存储过程,它不同于我们前面介绍过的存储过程。触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行诸如Update、Insert、Delete这些操作时,SQL Server就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合由这些SQL语句所定义的规则。

触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。除此之外,触发器还有其他许多不同的功能:

(1)强化约束(Enforce restriction)

触发器能够实现比CHECK语句更为复杂的约束。

(2)跟踪变化Auditing changes

触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。

(3)级联运行(Cascaded operation)。

触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作又导致该表上触发器被触发。

(4)存储过程的调用(Stored procedure invocation)。

为了响应数据库更新,触发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS(数据库管理系统)本身之外进行操作。

由此可见,触发器可以解决高级形式的业务规则或复杂行为限制以及实现定制记录等一些方面的问题。例如,触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理。此外一个表的同一类型(Insert、Update、Delete)的多个触发器能够对同一种数据操作采取多种不同的处理。

总体而言,触发器性能通常比较低。当运行触发器时,系统处理的大部分时间花费在参照其他表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其他表的位置决定了操作要花费的时间长短。

2.触发器种类

SQL Server 2000支持两种类型的触发器:AFTER触发器和INSTEAD OF触发器。其中AFTER触发器即为SQL Server 2000版本以前所介绍的触发器。该类型触发器要求只有执行某一操作(Insert Update Delete)之后,触发器才被触发,且只能在表上定义。可以为针对表的同一操作定义多个触发器。对于AFTER触发器,可以定义哪一个触发器被最先触发,哪一个被最后触发,通常使用系统过程sp_settriggerorder来完成此任务。

INSTEAD OF触发器表示并不执行其所定义的操作(Insert、Update、Delete),而仅是执行触发器本身。既可在表上定义INSTEAD OF触发器,也可以在视图上定义INSTEAD OF触发器,但对同一操作只能定义一个INSTEAD OF触发器。

3.常用格式

Create procedure procedure_name

[@parameter data_type][output]

[with]{recompile|encryption}

as

sql_statement

解释:

output:表示此参数是可传回的

with{recompile|encryption}

recompile:表示每次执行此存储过程时都重新编译一次

encryption:所创建的存储过程的内容会被加密

如:

表book的内容如下:

编号 书名 价格

001 C语言入门$30

002 PowerBuilder报表开发$52

实例1:查询表Book的内容的存储过程

create proc query_book

as

select*from book

go

exec query_book

实例2:

加入一笔记录到表book,并查询此表中所有书籍的总金额

Createprocinsert_book

@param1char(10),@param2varchar(20),@param3money,@param4moneyoutput(www.xing528.com)

withencryption---------加密

as

insertintobook(编号,书名,价格)Values(@param1,@param2,@param3)

select@param4=sum(价格)frombook

go

执行例子:

declare@total_pricemoney

execinsert_book'003','Delphi控件开发指南',$100,@total_price

print'总金额为'+convert(varchar,@total_price)

go

存储过程的3种传回值:

(1)以Return传回整数

(2)以output格式传回参数

(3)Recordset

传回值的区别:

output和return都可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中。

实例3:

设有两个表为Product,Order_,其表内容如下:

Product

产品编号 产品名称 客户订数

001钢笔30

002毛笔50

003铅笔100

Order_

产品编号 客户名 客户订金

001南山区$30

002罗湖区$50

003宝安区$4

请实现按编号为连接条件,将两个表连接成一个临时表,该表只含编号.产品名.客户名.订金.总金额,

总金额=订金*订数,临时表放在存储过程中

代码如下:

Create proc temp_sale

as

select a.产品编号,a.产品名称,b.客户名,b.客户订金,a.客户订数*b.客户订金as总金额

into #temptable from Product a inner join Order_b on a.产品编号=b.产品编号-----此处要用别名

if@@error=0

print'Good'

else

print'Fail'

go

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈