我们对于防止学生重复登录机房收费系统的做法通常是在表中添加一个标记学生上机状态的字段,然后根据上、下机的操作来修改该字段。那么这么做的问题是,但程序出现异常而奔溃时下机操作将不被执行。那么也就是用户就会一直处于在线状态而无法登录。因此根据临时表自动回收的特性,我们使用它来实现防止重复登录的功能。
先简单介绍一下sql Server中的临时表。临时表是临时性的文件,它被存储于系统数据库的Tempdb数据库下。分为局部临时表和全局临时表两种,分别有着不同的权限和生存周期。局部临时表是有当前用户创建的,并且只有当前用户的会话才可以访问,当创建该表的链接断开时临时表就自动删除。而全局临时表可以被所有用户可见,只有当所有用户的链接断开后才自动删除。所以,我们需要关心的重点是临时表到底在什么时候被删除?我们需要避免出现的情况是,我们还需要用到它的时候它已经被删除了或者我们不用了临时表却一直不被删除。
为了更好的把握临时表的生命周期,即它到底何时被回收。我们还是需要先了解VB.NET的连接池。连接池是.NET Framework为了节省打开和关闭数据库连接的资源开支提高性能的一种机制。即当sqlConnection的对象close时甚至被处理,sql的连接并不实际关闭和数据库的内部连接,而是将其保存到连接池中,以便之后再次使用。连接池里的连接在超出lifetime属性时或者未使用的连接超出了连接池规定的数量是,将会被销毁。那么其工作的机制如图所示:
好了,相信对与临时表和连接池有了一定的认识了。我们现在讲如何应用临时表来实现对用户重复登录的限制!根据用户登录的功能和程序生存周期一致,们选用全局临时表,因为全局临时表为所有用户可见,且只有当所有连接断开时才会自动回收,换句话说就是只要程序还活着临时表就不会被删除。
在数据库中建立存储过程,用来操作或者创建临时表:
ALTER PROCEDURE [dbo].[CreateStuT]
@CardID varchar(10),--传入参数,卡号
@Stu varchar(10) =null --查询结果
as
begin
if OBJECT_ID ('tempdb..##StuTemp') is not null --临时表存在
begin
select @Stu = CardID from ##StuTemp where CardID=@CardID --查询卡号
if @Stu is null --卡号不在在
begin
insert ##StuTemp (CardID) values (@CardID)
return '1' --表示登录成功
end
else
begin
return '0' --表示登录失败
end
end
else --临时表不存在
CREATE TABLE ##StuTemp ( CardID varchar(10) PRIMARY KEY )
insert ##StuTemp (CardID) values (@CardID)
return '1' --表示登录成功
end
VB.NET端的调用:
Cmd = New sqlClient.sqlCommand("CreateStuT",New sqlClient.sqlConnection(StrCon))
Cmd.Connection.open()
Cmd.CommandType = CommandType.StoredProcedure
Cmd.Parameters.Add(New sqlClient.sqlParameter("@CardID","卡号")
Cmd.Parameters.Add(New sqlClient.sqlParameter("@return",sqlDbType.BigInt))
Cmd.Parameters("@return").Direction = ParameterDirection.ReturnValue
Try
If Cmd.ExecuteNonQuery() = 1 Then
Return Cmd.Parameters("@return").Value
Else
Return 0
End If catch ex as Exception
End Try
至此,这个功能实现完成。临时表使用的重点就是它的自动删除的特性,以及它到底什么时候被删除!因此,对于VB.Net连接池的理解非常重要。有关连接池的内容下一篇博客会详细介绍,敬请期待!