存储过程的触发器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了存储过程的触发器相关的知识,希望对你有一定的参考价值。
参考技术A 触发器是一种特殊类型的存储过程,它不同于我们前面介绍过的存储过程。触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行诸如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)的多个触发器能够对同一种数据操作采取多种不同的处理。
总体而言,触发器性能通常比较低。当运行触发器时,系统处理的大部分时间花费在参照其它表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其它表的位置决定了操作要花费的时间长短。 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 触发器。 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,并查询此表中所有书籍的总金额 Create proc insert_book@param1char(10),@param2varchar(20),@param3money,@param4moneyoutputwith encryption---------加密asinsert into book(编号,书名,价格)Values(@param1,@param2,@param3)select @param4=sum(价格) from bookgo执行例子:declare @total_price moneyexec insert_book \'003\',\'Delphi控件开发指南\',$100,@total_price outputprint \'总金额为\'+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
关于存储过程
什么是存储过程?
- 存储过程(Stored Procedure)是在数据库系统中,一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程中的名字并给出参数(如果该存储过程带有参数)来执行它。
- 存储过程不仅仅是"批处理"。
- 存储过程是经过编译的SQL语句集。
存储过程与函数和触发器的区别?
- 从语法上看,存储过程和函数以及触发器是十分类似的。我们甚至可以说,触发器和函数就是一种特殊的存储过程。不过它们之间还是有一些区别的。
- 触发器用于完成一些触发条件所引起的操作。触发器的执行是自动化的。
- 自定义函数只能通过return语句返回单个值或者表对象,而存储过程不能调用return语句,但是可以通过out参数返回多个值。函数可以在SQL语句中结合使用。函数不能用临时表,只能用表变量,还有一些系统函数都不可用等等。
- 存储过程用于完成一系列的SQL操作,批量化的完成数据库操作工作,由使用者调用执行。
为什么使用存储过程?
- 存储过程只在创造时进行编译,以后每次执行存储过程都不需要再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
- 当对数据库进行复杂操作时(如对多个表进行Update、Insert、Query、Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事物处理结合一起使用。这些操作,如果用程序来完成,就变成一条条的SQL语句,可能要多次连输数据库,而换作存储过程,只需要连接一次数据库就可以了。
- 存储过程可以重复使用,可减少数据库开发人员的工作量。
- 安全性高,可设定只有某用户才具有对指定存储过程的使用权限。
为什么不使用存储过程?
可移植性差。
- 对于很简单的SQL语句,存储过程没有什么优势。
- 存储过程中不一定会减少网络传输。
- 如果只有一个用户使用数据库,那么存储过程从安全上讲也没什么优势。
- 团队开发时需要先统一标准。否则后期维护时个麻烦。
- 在大并发量访问的情况下,不宜写过多涉及运算的存储过程。
- 业务逻辑复杂时,特别是涉及到对很大的表进行操作的时候,不如在前端先简化业务逻辑。
存储过程中变量定义
- MySQL中使用DECLARE进行变量定义。用法:DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
- 其中,dataype为MySQL的数据类型,例如: int, float, date, varchar(length)
- 例如:
DECLARE I_int int unsigned default 4000000; DECLARE I_numeric number(8,2) DEFAULT 9.95; DECLARE I_date date DEFAULT ‘1999-12-31’; DECLARE I_datetime datetime DEFAULT ‘1999-12-31 23:59:59‘; DECLARE I_varchar varchar(255) DEFAULT ‘This will not be padded‘;
存储过程中变量赋值
MySQL中使用SET命令进行变量赋值。语法:SET 变量名 = 表达式 [,variable_name = expression ...]
注意:变量赋值是可以在不同存储过程中继承的。
mysql> SET @last_procedure=‘p1‘;
一个简单的例子
以上是关于存储过程的触发器的主要内容,如果未能解决你的问题,请参考以下文章