我使用此代码但无法关闭连接
cnnstr = " Data Source=.\SQLEXPRESS;AttachDbFilename=" & CurDir() & "\datastore.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"
Dim con As New SqlConnection(cnnstr())
Dim com As New SqlCommand("insert into tblbackuphistory values('" & dateshamsi & "','" & saat & "','" & mas & "',N'" & user & "')", con)
If con.State = ConnectionState.Closed Then
con.Open()
End If
com.ExecuteNonQuery()
com.Cancel()
com.Connection.Close()
con.Close()
com.Connection.Dispose()
con.Dispose()
答案 0 :(得分:4)
如果Open()
或ExecuteNonQuery()
引发异常,那么之后的.Close()
次调用都不会执行。这就是为什么你应该总是使用Try/Finally
块来做这样的事情,并且可以用Using
块缩短。
虽然我在这里,但这段代码对于sql注入攻击来说不仅仅是一个小小的可用性。对于仅作为已安装程序的本地数据存储而存在的数据库可能没问题(没有人关心用户是否想要在他们拥有的数据库中注入数据),但sql字符串的字符串连接仍然是一个坏习惯。如果你最终得到一个带撇号的用户名,会发生什么?
此代码修复了这两个问题:
cnnstr = " Data Source=.\SQLEXPRESS;AttachDbFilename=" & CurDir() & "\datastore.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"
Using con As New SqlConnection(cnnstr),
cmd As New SqlCommand("insert into tblbackuphistory values( @dateshamsi, @saat, @mas, @user)", con)
cmd.Parameters.Add("@dateshamsi", SqlDbType.DateTime).Value = Convert.ToDatetime(dateshamsi)
'guessing at column lengths here
cmd.Parameters.Add("@saat", SqlDbType.VarChar, 50).Value = saat
cmd.Parameters.Add("@mas", SqlDbType.VarChar, 50).Value = mas
cmd.Parameters.Add("@user", SqlDbType.NVarChar,50).Value = user
con.Open()
cmd.ExecuteNonQuery()
End Using
但是,根据标题中的错误,这不是整个故事。听起来连接字符串是错误的,因为datastore.mdf
文件已经附加到数据库服务器。如果您刚使用Sql Server Management Studio创建此数据库,则不需要附加它(AttachDbFileName
部分)。您只需将字符串中的Database=
选项设置为您的数据库名称。
Sql Server Express作为永远在线服务运行。它仍然是一个服务器级引擎,并且不太适合作为简单的本地数据存储,即使它可以以这种方式工作。它真正适用于小型工作组和网站。如果您只想为您的应用程序使用本地数据存储,请使用Sql Server Compact,Sql Server LocalDb,SqlLite甚至MS Access。