早在数据库的时候就对存储过程和事务有了一个基本了解,可是从来没实战过,这次机房重构有机会用一下,真的很好哎,好了,废话不多说,我们来了解一下怎么使用吧。
一、存储过程
1、定义:
存储过程是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
2、使用:
(1)创建存储过程
create procedure sp_name @[参数名] [类型],@[参数名] [类型] as begin ......... end(2)调用存储过程
基本语法:exec sp_name [参数名](3)删除存储过程
drop procedure sp_name2.注意事项
3、优缺点:
优点:
(1)重复使用;
(2)减少网络流量;
(3)安全性。
缺点:
(1)调试麻烦
(2)移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。
(3)重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译。
(4)如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。
二、事务
定义:
事务,一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
三、存储过程+事务实现注册:
ALTER PROCEDURE [dbo].[PROC_Regist] -- Add the parameters for the stored procedure here @Cardno char(10), @StudentNo char(10), @Cash varchar(50), @Type char(50), @Status char(50), @registDate char(10), @registTime char(10), @Holder char(10), @StudentName char(10), @Sex char(10), @Department char(10), @Grade char(10), @onClass char(10), @reDate char(10), @reTime char(10), @AddMoney char(10), @reHolder char(10) AS BEGIN DECLARE @Err1 INT,@Err2 INT,@Err3 INT--定义错误计数器 BEGIN TRANSACTION--开始事务 --添加卡表 insert into T_CardInfo (Cardno ,Cash,Type,Status ,registDate ,registTime ,Holder) values (@Cardno,@Cash,@Type,@Status,@registDate ,@registTime ,@Holder) set @err1=@@error--出错给错误计数器赋值,变量不为0 --添加学生表 insert into T_StudentInfo (Cardno,StudentNo,StudentName ,Sex,Department ,Grade,onClass,Holder)values (@Cardno,@StudentNo,@StudentName,@Sex,@Department ,@Grade,@onClass,@Holder) set @Err2=@@error--出错给错误计数器赋值,变量不为0 --添加到充值记录表 insert into T_RechargeInfo (Cardno,AddMoney,ReDate,ReTime,Status,reHolder)values (@cardno,@reDate,@reTime,@AddMoney,@Status,@reHolder) set @err3=@@ERROR--出错给错误计数器赋值,变量不为0 if @Err1=0 and @Err2=0 and @err3=0--判断错误计数器中的值是否为0 COMMIT TRANSACTION--提交事务 ELSE ROLLBACK TRANSACTION--回滚,回到原始状态 END
D层代码展示:
Dim sql As String = "PROC_Regist" '创建存储过程的名字 Dim sqlparams As SqlParameter() = {New SqlParameter("@Cardno", e_stucard.Cardno), New SqlParameter("@Type", e_stucard.Type), New SqlParameter("@Status", e_stucard.Status), New SqlParameter("@Holder", e_stucard.Holder), New SqlParameter("@StudentNo", e_stucard.Studentno), New SqlParameter("@StudentName", e_stucard.StudentName), New SqlParameter("@Grade", e_stucard.Grade), New SqlParameter("@Department", e_stucard.Department), New SqlParameter("@onClass", e_stucard.onClass), New SqlParameter("@Sex", e_stucard.Sex), New SqlParameter("@registDate", e_stucard.registDate), New SqlParameter("@registTime", e_stucard.registTime), New SqlParameter("@reDate", e_recharge.reDate), New SqlParameter("@reTime", e_recharge.reTime), New SqlParameter("@Cash", e_stucard.Cash), New SqlParameter("@AddMoney", e_recharge.AddMoney), New SqlParameter("@reHolder", e_recharge.reHolder)} Dim flag As Boolean flag = sqlhelper.ExecAddDelUpdate(sql, CommandType.StoredProcedure, sqlparams) Return flag四、总结
在用存储过程时遇到不少问题,但都顺利解决了,有很多细节的问题,感悟就是敲代码要带着脑子,还要细心+认真,否则小小的错误就会让我们失去很多时间。