在机房收费系统中,涉及三个组合查询,分别是学生基本信息维护、学生上机状态查看、操作员工作记录;如何让三个组合查询使用同一个存储过程,就需要我们转转小小的脑袋,几经周折,发现,我们可以把表名当成一个参数进行传递,这样,用到不同表的时候,我们只需要变更表名即可,存储过程写法如下所示:
<span style="font-size:18px;"><span style="font-size:18px;">USE [MachineRoomChargeSystem] GO /****** Object: StoredProcedure [dbo].[Proc_GroupQuery] Script Date: 08/01/2014 19:24:15 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <丁国华> -- Create date: <2014年7月31日 20:08:32> -- Description: <组合查询--学生上机状态查看,操作员工记录> -- ============================================= ALTER PROCEDURE [dbo].[Proc_GroupQuery] -- Add the parameters for the stored procedure here @cboFieldA varchar(10), --字段名A @cboOperatorA varchar(10), --操作符A @txtContentA varchar(10), --要查询的内容A @cboRelationA varchar(10), --组合关系A @cboFieldB varchar(10), --字段名B @cboOperatorB varchar(10), --操作符B @txtContentB varchar(10), --要查询的内容B @cboRelationB varchar(10), --组合关系B @cboFieldC varchar(11), --字段C @cboOperatorC varchar(10), --操作符C @txtContentC varchar(10), --要查询的内容C @tableName varchar(50) --要查询的视图名或表面名 AS declare @strText varchar(500)--临时存放sql语句 --CHAR(32)是空格,CHAR(39)单引号 BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. set @strText ='select * from '+@tableName+' where status !='+CHAR(39)+'正常上机'+CHAR(39)+' and status !='+char(39)+'正在值班'+CHAR(39)+' and'+CHAR(32) +@cboFieldA+@cboOperatorA+CHAR(39)+@txtContentA +CHAR(39) if @cboRelationA!='' begin set @strText=@strText+@cboRelationA+CHAR(32)+ @cboFieldB+@cboOperatorB+CHAR(39 )+@txtContentB+CHAR(39) end if @cboRelationB!='' begin set @strText=@strText+@cboRelationB+CHAR(32)+ @cboFieldC+@cboOperatorC+CHAR(39)+@txtContentC+CHAR(39) end execute(@strText) END </span></span>E---实体层写法如下:
<span style="font-size:18px;"><span style="font-size:18px;">'********************************************** '文 件 名: GroupQueryEntity '命名空间: Entity '内 容: '功 能: 组合查询 '文件关系: '作 者:丁国华 '小 组:宝贝计划 '生成日期: 2014/7/31 21:33:57 '版本号:V2.0 '修改日志: '版权说明: '********************************************** Public Class GroupQueryEntity ''' <summary> ''' 组合查询用到的一系列实体 ''' </summary> ''' <remarks></remarks> Private _cboFieldA As String Public Property cboFieldA() As String Get Return _cboFieldA End Get Set(value As String) _cboFieldA = value End Set End Property Private _cboOperatorA As String Public Property cboOperatorA() As String Get Return _cboOperatorA End Get Set(value As String) _cboOperatorA = value End Set End Property Private _txtContentA As String Public Property txtContentA() As String Get Return _txtContentA End Get Set(value As String) _txtContentA = value End Set End Property Private _cboRelationA As String Public Property cboRelationA() As String Get Return _cboRelationA End Get Set(value As String) _cboRelationA = value End Set End Property Private _cboFieldB As String Public Property cboFieldB() As String Get Return _cboFieldB End Get Set(value As String) _cboFieldB = value End Set End Property Private _cboOperatorB As String Public Property cboOperatorB() As String Get Return _cboOperatorB End Get Set(value As String) _cboOperatorB = value End Set End Property Private _txtcontentB As String Public Property txtcontentB() As String Get Return _txtcontentB End Get Set(value As String) _txtcontentB = value End Set End Property Private _cboRelationB As String Public Property cboRelationB() As String Get Return _cboRelationB End Get Set(value As String) _cboRelationB = value End Set End Property Private _cboFieldC As String Public Property cboFieldC() As String Get Return _cboFieldC End Get Set(value As String) _cboFieldC = value End Set End Property Private _cboOperatorC As String Public Property cboOperatorC() As String Get Return _cboOperatorC End Get Set(value As String) _cboOperatorC = value End Set End Property Private _txtContentC As String Public Property txtContentC() As String Get Return _txtContentC End Get Set(value As String) _txtContentC = value End Set End Property Private _tableName As String Public Property tableName() As String Get Return _tableName End Get Set(value As String) _tableName = value End Set End Property End Class </span></span>D层如下:就学生上机状态查询来说:
<span style="font-size:18px;"><span style="font-size:18px;">'********************************************** '文 件 名: T_LineDAL '命名空间: DAL '内 容: '功 能: '文件关系: '作 者:丁国华 '小 组:宝贝计划 '生成日期: 2014/7/25 10:39:13 '版本号:V2.0 '修改日志: '版权说明: '********************************************** ''' <summary> ''' 组合查询-学生上机状态查看 ''' </summary> ''' <param name="enGroupQuery"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function queryStatus(enGroupQuery As Entity.GroupQueryEntity) As List(Of Entity.LineEntity) Implements ILine.queryStatus Dim strText As String = "Proc_GroupQuery" '从存储过程里面查询相应信息 Dim cmdType As String = CommandType.StoredProcedure '命令类型 Dim parameter As SqlParameter() '传参 parameter = {New SqlParameter("@cboFieldA", enGroupQuery.cboFieldA), New SqlParameter("@cboOperatorA", enGroupQuery.cboOperatorA), New SqlParameter("@txtContentA", enGroupQuery.txtContentA), New SqlParameter("@cboRelationA", enGroupQuery.cboRelationA), New SqlParameter("@cboFieldB", enGroupQuery.cboFieldB), New SqlParameter("@cboOperatorB", enGroupQuery.cboOperatorB), New SqlParameter("@txtContentB", enGroupQuery.txtcontentB), New SqlParameter("@cboRelationB", enGroupQuery.cboRelationB), New SqlParameter("@cboFieldC", enGroupQuery.cboFieldC), New SqlParameter("@cboOperatorC", enGroupQuery.cboOperatorC), New SqlParameter("@txtContentC", enGroupQuery.txtContentC), New SqlParameter("@tableName", enGroupQuery.tableName)} Dim sqlHelper As New SqlHelper Dim dt As New DataTable Dim myList As List(Of Entity.LineEntity) dt = sqlHelper.ExecuteReaderTable(strText, cmdType, parameter) myList = EntityHelper.convertToList(Of Entity.LineEntity)(dt) Return myList End Function End Class</span></span>对实体进行封装,把先前需要传递的十一个参数转换成现在只需要传递一个实体即可,还有一个细节问题需要注意的是,在存储过程里面SQL语句where后面的条件该如何写nie?就学生查看上机记录和操作员工作记录来说,第一个组合查询涉及到的状态有正常上机,正常下机,强制下机;第二个组合查询涉及到的状态有正在值班和下班两种状态,我们的第一个组合查询的业务需求是查出来的信息是状态不等于正常上机的相关信息,第二个组合查询的业务需求是状态不等于正在值班的相关信息,那么在where后面的条件到底是用and连接还是用or连接,小伙伴们都知道and的意思是和,连词,连接两个并列结构,or是或者的意思,整到这里,我就开始整蒙圈了,到底是用or还是用and呢?开始我的第一反应用的是or,要么执行这个,要么执行那个,别着急,让我们用实话说话,焦点访谈,呵呵,开个玩笑,在SQL中新建查询,看看用and连接,会发生什么好玩儿的事儿呢?
接着,用or连接:
进过对比,我们发现,第一个用and连接,查询出来的信息的状态包括正常上机的和正常下机的,但是根据机房收费系统的业务需求,需要我们查询出来的信息是正常下机的,显然第二个才是我们所需要的信息,聪明的读者,明白了么?
对比我们之前学习过的vb中的函数过程和我们的存储过程,有什么不一样的地方呢?存储过程不一定非要有返回值数据库中的函数一定有返回值;存储过程在前台语言可以直接调用 而函数一般要有sql语句做为载体;用户自定义函数在处理同一数据行中的各个字段时,特别方便有用。虽然这里使用存储过程也能达到查询目的,但是显然没有使用函数方便。而且,即使使用存储过程也无法处理SELECT查询中的同一数据行中的各个字段的运算。因为存储过程不返回值,使用时只能单独调用;而函数却能出现在能放置表达式的任何位置。第二版机房收费系统,未完,待续......