存储过程的触发器

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

参考技术B 所谓存储过程,是一组预编译的Transact-SQL语句,存储在SQL Server中,被作为一种数据库对象保存起来。存储过程的执行不是在客户端而是在服务器端(执行速度快)。存储过程可以是一条简单的Transact-SQL语句,也可以是复杂的Transact-SQL语句和流程控制语句的集合。 在使用Transact-SQL语言编程的过程中,我们可以将某些需要多次调用的实现某个特定任务的代码段编写成一个过程,将其保存在数据库中,并由SQL Server服务器通过过程名来调用它们,这些过程就叫做存储过程(也称为子程序)。 存储过程在第一次执行时进行语法检查和编译,编译好的版本存储在高速缓存中,用于后续调用,下次调用时可以直接执行。 存储过程的特点: 存储过程可以接受输入参数,并且可以用输出参数的形式返回值。存储过程可以包含复杂的流控制语句。 存储过程建立好以后可以被反复调用。一个存储过程可以调用另一个存储过程,嵌套调用可多达32级。 由于存储过程在建立和第一次执行的时候被解析、优化、编译和缓存(驻留在高速缓冲存储器中),因此其执行速度比直接向SQL Server发送T-SQL语句快。 存储过程的执行是通过一条语句来完成的,避免了网络上服务器和客户机之间大量Transact-SQL语句的传送,降低了网络的通信量。 存储过程可以被看作一种安全机制,即使用户没有对表或视图的访问权限,他们也可以被授予执行对表或视图进行访问的存储过程的权限。 、、、、、、、、、、、、、、、、、、、、、、、、、、、 触发器的作用 在指定的表中数据发生变化时被调用以响应INSERT、UPDATE或DELETE事件。 用于保护表中的数据,当有操作影响到触发器保护的数据时,触发器自动强制执行业务规则。 利用触发器可以方便地实现数据库中的数据完整性。 一般的存储过程通过存储过程名称被直接调用,而触发器主要是通过事件进行触发而被执行(对表或视图发出update、insert、delete语句)。 触发器是一个功能强大的工具,它与表格紧密相连,在表中数据发生变化时自动强制执行。触发器可以用于SQL Server约束、默认值和规则的完整性检查,还可以完成难以用普通约束实现的复杂功能。 触发器的优点 触发器是自动的执行的(往表里插入、修改、删除时被自动激活,从而防止对数据的不正确修改)。 触发器是基于一个表创建的,但可以针对多个表进行操作,实现数据库中的相关表进行层叠更改。 触发器可以实现比 check约束更为复杂的数据完整性约束。 一个表中可以同时存在三个不同操作的触发器,对于同一个修改语句可以有多个不同的对策以响应。

关于存储过程

什么是存储过程?

  • 存储过程(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‘;

 

一个简单的例子

技术分享图片

以上是关于存储过程的触发器的主要内容,如果未能解决你的问题,请参考以下文章

oracle 存储过程与触发器

存储过程、索引、视图、触发器 的区别

存储过程触发器数据完整性

oracle存储过程和存储函数&触发器

expdp怎么导出存储过程 函数 触发器等

查看表、存储过程、触发器、函数等对象定义语句