存储过程
what
一堆SQL语句+流程控制编写的模块
when
数量大且比较复杂的业务(比如当完成一个功能需要好几张表时,可以用存储过程,只需打开一次数据库;若不用存储过程,你得写好几个调用表的方法,连接好几次数据库)
优点
- 提高运行速度
- 存储过程在创建时进行编译,在调用存储过程的时候,其执行的SQL语句大部分准备工作都已完成;而交互执行的SQL语句是编译执行的,所以速度较慢
- 增强了SQL的功能和灵活性
- 存储过程的sql语句可以加逻辑判断和复杂的运算(所以说存储过程用于业务复杂的情况下,这样可以一个存储过程完成多个功能,不必一个个调用数据库)
- 减轻程序员编写的工作量
- 不同的程序员可以重复的调用存储过程
- 降低网络的通信量
- 文章开头就给出了存储过程中包括流程控制,所以必有逻辑判断流程,而存储过程是放在服务器端的,所以只需向服务器请求一次;避免了交互模式下在处理逻辑时产生的中间通信开销
- 提高安全性
- 限定只有某些用户才有对此存储过程的使用权;当不允许某些用户直接在表或视图上进行查询时,可通过授权使用存储过程来解决
缺点
- 可移植性差
- 存储过程将应用程序绑定到SQL Server(注:移植性不是指将程序不做修改就可以放到任何环境中运行,只是说修改的少)wd=csdn)
不易修改
- 存储过程将应用程序绑定到SQL Server(注:移植性不是指将程序不做修改就可以放到任何环境中运行,只是说修改的少)wd=csdn)
- 列表内容
- 当需求改变时,比如增加一个参数,还要更改底层代码
- 不是面向对象
- sql语句+控制,本质上还是过程化的,面对复杂的业务逻辑,过程化的处理不方便
事务
what
构成单一逻辑工作单元的操作集合
why
事务的性质:
1. 原子性
2. 一致性
3. 隔离性
4. 持久性
由上面的性质可知其一:能保证事务要么完整的执行,要么不执行
下面是我写的一个简单的存储过程+事务
ALTER PROCEDURE [dbo].[pro_OffLine]
@StuNum int,
@Cash money,
@OffDate datetime,
@ConsumeCash money,
@ConsumeTime int,
@State varchar(8)
AS
BEGIN
declare @error int
set @error=0
Begin transaction --开始一个事务
update T_student set cash=@Cash where stuNum=@StuNum --更新学生表
set @error=@error+@@ERROR
update T_lineRecord set offDate=@OffDate,consumeCash=@ConsumeCash,consumeTime=@ConsumeTime,[state]=@State where stuNum=@StuNum --更新上机记录表
set @error=@error+@@ERROR
if @error<>0
rollback transaction --回滚事务,不执行
else
commit transaction --执行事务
END
GO
【注解】
- @@error是系统函数,当没发生错误是,返回0;发生错误是返回错误行号,所以我们这定义一个变量@error,接收@@errror的值,如果最后@error=0说明没发生错误
- 什么时候会发生事务回滚那???
只要你的代码没有书写上的本质错误,他就不会回滚,比如在上面的存储中,第一条更新T_student表中stuNum为1的学生记录,而第二条也更新stuNum为1的T_lineRecord表,但此时上机记录表中没有stuNum为1的学生,此时是不会报错的,因为代码本身没有错,那是你表逻辑或结构上设计的不合理,正常情况下上机记录表中是有stuNum=1的学生的(就这个问题想了半天才明白过来,开始我就认为既然我表里没有记录,无法操作,就是发生错误了,就得事务回滚);而如果当你的参数@State声明的int,而数据库中定义的是varchar(50),这时就是代码本质错误了,就会发生事务回滚,第一张表也不会更新;
【总结】
- 当遇到一个问题时,坚持一下,前往不要放过,你掌握了这个知识点,那你就超越了自己,或许就知道了别人不明白的,此时又比别人进步了一点;
- 如果放过,以后你肯定还会遇到,迟早会学得,还不如早点学,早点应用,早点解决问题,要有不将就的心;
友情连接一篇有关存储过程与触发器的比较:存储过程VS触发器