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

Sey*_*ade 0 .net sql 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()
Run Code Online (Sandbox Code Playgroud)

Joe*_*orn 5

如果有异常抛出由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
Run Code Online (Sandbox Code Playgroud)

但是,根据标题中的错误,这不是故事的全部。听起来连接字符串是错误的,因为datastore.mdf文件已经附加到数据库服务器。如果您只是使用 Sql Server Management Studio 创建了这个数据库,则不需要附加它(AttachDbFileName部分)。您只需将Database=字符串中的选项设置为您的数据库名称。

Sql Server Express 作为永远在线的服务运行。它仍然是一个有效的服务器级引擎,并不适合作为简单的本地数据存储,即使它可以那样工作。它确实适用于小型工作组和网站。如果您只想为您的应用程序创建本地数据存储,请使用 Sql Server Compact、Sql Server LocalDb、SqlLite 甚至 MS Access。