我有一個公共子將記錄集合從一個表移動到同一個 SQLite 資料庫中的另一個。首先它從 strFromTable 中讀取一條記錄,然后將其寫入 strToTable,然后從 strFromTable 中洗掉該記錄。為了加快速度,我已將整個記錄集合加載到事務中。當串列涉及移動大量影像 blob 時,資料庫會被備份,并引發例外“資料庫已鎖定”。我認為正在發生的事情是它在開始嘗試寫入下一條記錄之前還沒有完成寫入一條記錄。由于 SQLite 一次只允許一次寫入,因此它會拋出“鎖定”例外。
以下是在移動大量影像 blob 時觸發錯誤的代碼:
Using SQLconnect = New SQLiteConnection(strDbConnectionString)
SQLconnect.Open()
Using tr = SQLconnect.BeginTransaction()
Using SQLcommand = SQLconnect.CreateCommand
For Each itm As ListViewItem In lvcollection
SQLcommand.CommandText = $"INSERT INTO {strToTable} SELECT * FROM {strFromTable} WHERE id = {itm.Tag}; DELETE FROM {strFromTable} WHERE ID = {itm.Tag};"
SQLcommand.ExecuteNonQuery()
Next
End Using
tr.Commit()
End Using
End Using
當我擺脫事務時,它會毫無錯誤地執行:
Using SQLconnect = New SQLiteConnection(strDbConnectionString)
SQLconnect.Open()
Using SQLcommand = SQLconnect.CreateCommand
For Each itm As ListViewItem In lvcollection
SQLcommand.CommandText = $"INSERT INTO {strToTable} SELECT * FROM {strFromTable} WHERE id = {itm.Tag}; DELETE FROM {strFromTable} WHERE ID = {itm.Tag};"
SQLcommand.ExecuteNonQuery()
Next
End Using
End Using
我對資料庫操作不是很好,所以我確信有些地方需要改進。有沒有辦法讓 SQLite 在執行下一個 INSERT 之前完全完成上一個 INSERT?如何更改我的代碼以允許使用交易?
謝謝您的幫助。
.
uj5u.com熱心網友回復:
好的......這是我決定采用的解決方案。我希望這有助于有人在搜索中找到它:
Dim arrIds(lvcollection.Count - 1) As String
Dim i as Integer = 0
' Load the array with all the Tags in the listViewCollection
For i = 0 to lvcollection.Count - 1
arrIds(i) = lvcollection(i).Tag 'item.Tag holds the Primary Key "id" field in the DB
Next
'build a comma-space separated string of all ids from the array of ids.
Dim strIds as String = String.Join(", ", arrIds)
Using SQLconnect = New SQLiteConnection(strDbConnectionString)
SQLconnect.Open()
Using tr = SQLconnect.BeginTransaction()
Using SQLcommand = SQLconnect.CreateCommand
SQLcommand.CommandText = $"INSERT INTO {strToTable} SELECT * FROM {strFromTable} WHERE id IN ({strIds});"
SQLcommand.ExecuteNonQuery()
SQLcommand.CommandText = $"DELETE FROM {strFromTable} WHERE ID IN ({strIds});"
SQLcommand.ExecuteNonQuery()
End Using
tr.Commit()
End Using
End Using
IN 陳述句允許我將所有要洗掉的“id”值作為批處理傳遞。這個解決方案比沒有交易的情況下一個一個地做更快、更安全。
感謝您的評論,并向編碼中的每個人致以最良好的祝愿。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/442648.html
