存储结构和事务

      重构的机房收费系统是用三层实现的,开始简单的增删改的时候还好说,可是当我做到充值退卡的的时候就发现我必须要学点新东西了,因为如果要进行退卡的画,首先我要把查到的信息插入到退卡表中,还要把卡的状态改成退卡状态,这就需要两条SQL语句,但是如果我写在一个函数中的话,第一,他们执行的顺序我就不能保证,第二,如果执行完插入,可是没有执行修改,那么这个卡还在,这就不是意见轻松的事了,所以这时候就发现好东西了,那就是存储结构和事务。

存储结构和事务

那么先大概介绍一下存储结构吧。复杂的介绍就不写了,我就把他理解成一个带有多条SQL语句的结构,结构是死的,只有语句是活的,那么我们就在死结构中加活语句就可以了。因为一个功能有很多时候不是一条语句可以解决的,所以大家就可以把这些语句多写进去,方法和在程序中写是一样的。

事务呢,他是保证存储结构中的SQL语句按顺序执行,且都执行完,负责都不知行,即使执行了前边的,也会让时间倒流。我们把他理解成一条衣服语句,if   语句1,语句2... else 全不执行 end if,这样是不是理解简单一下,而且用起来,更简单。

如果创建存储过程呢?

右键存储过程,点击新建存储过程,然后照着模版敲就可以了

下面我就把机房收费系统的退卡代码和存储结构,事务给大家展示出来,让大家看看他有多简单。但是因为这个程序我还没有完善,所以这只是基本功能的实现,在我完成系统后,会把完善好的代码为大家呈现上来。

存储过程加事务

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:18px;">USE [jf_Charge]
GO
/****** Object:  StoredProcedure [dbo].[Pro_CancelCard]    Script Date: 07/28/2014 19:41:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:孟海滨
-- Create date: 2014-7-27
-- Description:	退卡存储过程
-- =============================================
ALTER PROCEDURE [dbo].[Pro_CancelCard]
	@Card_ID char(11),@head char(11)    --定义参数
	
AS
BEGIN tran			--执行事务

	SET NOCOUNT ON;
DECLARE @SumRowCount INT --申明一个变量,用来判断语句成功了几天。

	declare @cancelMoney numeric(18,1)	--申明变量
	declare @Student_Name char(11)
	
	SET @SumRowCount=@@ROWCOUNT
	Select * from StudentView  Where Card_ID=@Card_ID	--从视图中获取学生信息
	SET @SumRowCount=@SumRowCount+@@ROWCOUNT
	
	set  @CancelMoney= (Select charge from StudentView Where Card_ID=@Card_ID)	--将查到的金额信息复制给@CancelMOney
	
		insert into CancelCard_info (Card_ID,CancelMoney,head ) values(@Card_ID,@cancelMoney ,@head ) --向退卡表中插入信息
	SET @SumRowCount=@SumRowCount+@@ROWCOUNT
		
		update Card_Info set IsExist='YES' where Card_ID=@Card_ID and IsExist='No'	--修改Card_info中的状态信息
	SET @SumRowCount=@SumRowCount+@@ROWCOUNT

IF @SumRowCount=4
	BEGIN 
		COMMIT TRAN	--如果都执行成功,那么开始执行事务
	END
ELSE
	BEGIN 
		ROLLBACK TRANSACTION  --如果不成功,会滚到以前,让时间倒流
	END

</span></span></span>


DAL层


<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:18px;">Imports Entity
Imports System.Data.SqlClient

Public Class SQLServerCancelCard : Implements IDAL.ICancelCard

    Public Function QueryCancelCard(cancel As CancelCardEntity) As CancelCardEntity Implements IDAL.ICancelCard.QueryCancelCard
        Return Nothing

    End Function
    ''' <summary>
    ''' 该方法用来退卡并利用存储过程,把退卡信息显示出来,其中需要执行多条语句,包括插入退卡信息
    ''' 修改卡信息的是否存在,并对视图的信息进行查询,并显示出来
    ''' </summary>
    ''' <param name="cancel"></param>
    ''' <returns>返回类型是StudentInfoEntity,因为退卡后显示的信息是需要从Student的信息中调用</returns>
    ''' <remarks></remarks>

    Public Function CancelCard(cancel As CancelCardEntity) As StudentInfoEntity Implements IDAL.ICancelCard.CancelCard
        Dim table As DataTable      '定义一个DataTable
        Dim cancelcardinfo As New Entity.StudentInfoEntity  '定义一个实体,用来返回数据

        Dim sqlhelper As New SqlHelper
        Dim User_ID As New PublicUserEnity  '公共实体,用来将登录者的姓名赋值给实体的属性
        Dim strSQL As String = "Pro_CancelCard"
        '定义参数,防止SQL注入
        Dim paras As SqlParameter() = {New SqlParameter("@Card_ID", cancel.Card_ID),
                                        New SqlParameter("@head", cancel.head)}
        '执行SQL语句,返回Datatable
        table = sqlhelper.ExecSelect(strSQL, CommandType.StoredProcedure, paras)

        '如果查询到的table不为空,那么就把他的部分值返回给实体属性,最后在返回实体
        If table.Rows.Count <> 0 Then
            cancelcardinfo.Student_Name = table.Rows(0).Item("Student_Name")
            cancelcardinfo.Charge = table.Rows(0).Item("Charge")
        End If

        '返回实体
        Return cancelcardinfo
    End Function
End Class
</span></span></span>

SQLHelper

<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:18px;"> ''' <summary>    
    ''' 执行查询的操作,(有参),参数不限    
    ''' </summary>    
    ''' <param name="cmdText">需要执行语句,一般是Sql语句,也有存储过程</param>    
    ''' <param name="cmdType">判断Sql语句的类型,一般都不是存储过程</param>    
    ''' <param name="paras">传入的参数</param>    
    ''' <returns></returns>    
    ''' <remarks></remarks>    
    Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable

        Dim sqlAdapter As SqlDataAdapter
        Dim dt As New DataTable
        Dim ds As New DataSet
        '还是给cmd赋值    
        cmd.CommandText = cmdText
        cmd.CommandType = cmdType
        cmd.Connection = conn
        cmd.Parameters.AddRange(paras)  '参数添加    
        sqlAdapter = New SqlDataAdapter(cmd)  '实例化adapter    
        Try
            sqlAdapter.Fill(ds)           '用adapter将dataSet填充     
            dt = ds.Tables(0)             'datatable为dataSet的第一个表    
            cmd.Parameters.Clear()        '清除参数    
        Catch ex As Exception
            MsgBox("查询失败", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "警告")
        Finally                            '最后一定要销毁cmd    
            Call CloseCmd(cmd)
        End Try
        Return dt
    End Function</span></span></span>

抽象工厂+接口+配置文件
Factory层
<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:18px;">Imports System.Configuration
Imports System.Reflection   '添加配置文件引用
Imports IDAL

Public Class DataAccess
    '配置文件,抽象工厂
    Private ReadOnly assemblyName As String = "DAL"
    Private ReadOnly db As String = ConfigurationManager.AppSettings("DB")
    Dim ClassName As String
    '创建退卡的抽象工厂
  
    Public Function CreateOnline() As IDAL.IOnline
        ClassName = assemblyName + "." + db + "CancelCardDAL"
        Return CType(Assembly.Load(assemblyName).CreateInstance(ClassName), ICancelCard)
    End Function
End Class
</span></span></span>
配置文件
<span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:18px;"><?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  
    <appSettings>
        <add key="strCnn" value="server=***.***.**.***;database=jf_Charge;uid=sa;pwd=123456" />
       <add key="DB" value="SQLServer"/>
     </appSettings>
      
  
      
</configuration></span></span></span>

因为这里介绍的是存储结构和事务,所以只是把相关的代码给大家,因为B层和U层和没有存储过程一样,这里就不再浪费大家的时间,其时大家也可以发现,他在程序中就是当成了一条SQL语句来执行的,具体的效果确不是在程序里边加几条SQL语句就能比的了的。
1.首先他的结构固定,学习也方便,我们需要改动的没有很
2.事务的作用尽管和If语句很想,但是我们在D层加太多的If难免就会觉得冗杂,但是事务不会。
3.运行效果他会更快,至于为什么,存储过程只在创造时进行编译,以后每次执行存储过程都不需要重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储提高数据库的执行速度。

你可能感兴趣的:(数据库,事务)