该进程无法访问该文件,因为该文件正由另一个进程使用

时间:2015-12-14 22:57:43

标签: sql .net vb.net

我使用此代码但无法关闭连接

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()

1 个答案:

答案 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。