机房收费系统里,一个功能的实现,有时会涉及到数据库里的很多张表。如果把这些都写进7层的代码会非常的繁琐,而且不易修改。存储过程,就恰好解决了这个难题。那么什么是存储过程呢?
是在大型数据库系统中,一组为了完成特定功能的SQL语句集。通俗一点,就是为了完成某一功能的SQL语句们写到一起,更好的完成该功能。
存储过程是写在数据库中的。以SQL server 2008为例,存储过程的位置在,“可编程性”目录下。
下面就以充值功能为例,来看看存储过程如何从理论到实践。
首先,我们要想想,充值功能究竟都涉及到了哪些表呢?
给账号充值,肯定是要给充值表一条充值记录的。所以,充值表是第一张。
另外,我们的账号在注册时就有金额的充值,所以账号在“充值功能”之前是有原始金额的,原始金额更新在学生表,卡表。所以,我们要选择其中一张来获取原始金额,那么,学生表/卡表就是第二张。
再来,充值后,你的金额肯定是原始金额加上充值金额,有了一个新的金额数。这个新的金额数需要更新到有金额字段的表里。学生表和卡表拥有 cash 金额这个字段,所以,学生表/卡表就是第三张表。
以上分析结束后,我们具体看看,存储过程怎么写。
右击新建存储过程之后,你会看到花花绿绿,英文代码一大堆,不过,大部分都是举例和解释。
本着绿色是注释色的最佳第六感,你可以选择把最上边的一大堆英文删掉。关于 author 和create date 等注释还是我们很熟悉的一些内容。建议填写完整,便于更好的记录。
蓝色的 “CREATE PROCEDURE”大家应该可以猜到是什么意思了吧,就是创建过程的意思。后面的
参数提供结束,再看下面的 AS BEGIN ,SET NOCOUNT ON 的意思是不返回计数,这里的计数,是指本存储过程的影响行数的计数。
再往下看,什么select 语句,就很熟悉了吧,就是我们的增删改的SQL语句啦。
经过小编的解释之后,是不是对存储过程有了一些熟悉感,多了一点点了解呢。最后,小编把自己 充值这块的存储过程贴出来,供大家参考。
USE [RoomCharge]
GO
/****** Object: StoredProcedure [dbo].[pro_ReCharge] Script Date: 06/19/2016 16:42:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
-- Create date:
-- Description:
-- =============================================
ALTER PROCEDURE [dbo].[pro_ReCharge]
--@cash是来自学生表的cash,学生表cash和卡表cash一致
@CardNo char(10),@StudentNo char(10),@AddMoney numeric(18,0),@UserID char(10),@Cash numeric(18,0)
AS
BEGIN
declare
@IsCheck char(10),@Date date,@Time time(7),@Money numeric(18,0),@SumMoney numeric(18,0)
set @Date = CONVERT(date,GETDATE())
set @Time = CONVERT(time(0),GETDATE())
set @IsCheck ='未结账'
--事务开始执行
BEGIN TRANSACTION
--向充值表里插入该条充值记录
insert into T_Recharge (CardNo ,StudentNo ,AddMoney ,Date ,Time ,UserID ,IsCheck ) values (@CardNo ,@StudentNo ,@AddMoney ,@Date ,@Time ,@UserID ,@IsCheck )
---从学生表获取原始金额赋值给money
select @Money=@Cash from T_Student where CardNo =@CardNo
--计算出要返回的总金额 SumMoney 等于原始金额money加上 addmoney
set @SumMoney = @Money+@AddMoney
--更新学生表的金额和卡表的金额,将summoney赋值给两张表的cash
update T_Student set Cash=@SumMoney where CardNo =@CardNo
update T_Card set Cash =@SumMoney where CardNo =@CardNo
if @@ERROR <>0
rollback --回滚
else
commit --执行
END
因为表与表之间还有一些联系,这几张表整体都奏效的时候,这个功能才是无误完成的。所以,为了避免出现,只完成了其中几个SQL语句功能的情况,我们引入了事务,就是上面存储过程里的TRANSACTION。
对于事务的一些实践还是比较简单的。 BEGIN TRANSACTION 就意味着,从这里开始就归 我事务管啦,写在 BEGIN TRANSACTION下的都会遵从事务的特性,if@@ERROR的条件判断就是检查下,所有增删改的SQL语句是否执行正常,正常了就是执行下去,不正常就回滚,将程序或数据恢复到上一次正确状态的行为。
之前自考有接触过事务,当时我们机智的用了一个英文单词来记忆事务的特性。是哪个单词呢?
先卖个关子,先来看看事务都有哪些特性。
原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
取每一个特性的首字母,ACID ,就是“酸的”的意思。事务的特性就是“酸”。有助于增加单词量和事务的学习,一箭双雕~
剩余七层里有关注册的代码就不再贴啦,和其它功能实现都是异曲同工的,希望读罢本篇后,有所收获~~byebye~~