2015-12-14 62 views
-1

我用這個代碼,但不能關閉連接,因爲它正被另一個進程使用

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

回答

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。

相關問題