我有一个查询,它使用一个表数组(存储为字符串数组)来遍历我的表并执行一组删除/更新查询。除了表名之外,查询是相同的,因此使用循环来迭代使用表名作为变量。
问题是,我的Delete查询锁定了表,之后Update查询运行得太快;我收到“db is locked”错误。
我需要两件事之一:
唯一的问题是存在父子关系,因此必须在子表之前更新父表(目前通过数组排序完成)。
这是当前代码(有时)产生“DB locked / in use”消息:
For i = 0 To UBound(tables)
'Delete all data first
sql = "DELETE * FROM " & tables(i)
DoCmd.RunSQL sql
'Update all data second
sql = "INSERT INTO " & tables(i) & " IN """ & toDB & """ SELECT " & tables(i) & " .* FROM " & tables(i) & " IN """ & fromDB & """;"
DoCmd.RunSQL sql
Next
应澄清:查询从相同的表中获取一个后端(fromDB
)行并将其推送到另一个后端(toDB
)行
编辑:在回答有关INSERT INTO
的问题时,我的问题是如果我向toDB
添加字段,如果我覆盖它将删除它们。我必须做这个后门方法的原因是因为数据库仍处于开发阶段,但也与select表一起使用。每天都会进行更新和功能改进。我也不能使用简单的split-backend,因为访问数据库的其他计算机并不总是在网络上(我们必须在它返回到网络时手动同步它),所以我在一个后端工作,它适用于另一个,相同(ish,减去我的架构更新)后端。
答案 0 :(得分:2)
您可以使用ADO而不是DoCmd.RunSQL来同步执行SQL。
Dim cmd As ADODB.Command
Dim cnn As New ADODB.Connection
Set cnn = CurrentProject.Connection
For i = 0 To UBound(tables)
Set cmd = New ADODB.Command
With cmd
.CommandType = adCmdText
.ActiveConnection = cnn
.CommandText = "DELETE * FROM " & tables(i)
.Execute
End With
Set cmd = New ADODB.Command
With cmd
.CommandType = adCmdText
.ActiveConnection = cnn
.CommandText = "INSERT INTO " & tables(i) & " IN """ & toDB & """ SELECT " & tables(i) & " .* FROM " & tables(i) & " IN """ & fromDB & """;"
.Execute
End With
Next
您还可以添加cnn.BeginTrans
和cnn.CommitTrans
来制作两个语句Atomic。
答案 1 :(得分:1)
尝试这样的操作(注意我已经评论了您的 DoCmd.RunSQL
。我用 db.Execute
更改了它:
Sub DeleteInsertData(tables() As String, toDB As String, fromDB As String)
Dim db As DAO.Database
Dim i As Integer
Dim SQL As String
Set db = CurrentDb()
For i = 0 To UBound(tables)
'Delete all data first
SQL = "DELETE * FROM " & tables(i)
db.Execute SQL, dbFailOnError
'DoCmd.RunSQL SQL
'Update all data second
SQL = "INSERT INTO " & tables(i) & " IN """ & toDB & """ SELECT " & tables(i) & " .* FROM " & tables(i) & " IN """ & fromDB & """;"
db.Execute SQL, dbFailOnError
'DoCmd.RunSQL SQL
Next
Set db = Nothing
End Sub
答案 2 :(得分:0)
我不是专家,但我认为你不需要DELETE部分。 SELECT INTO是制作表格的语法。如果表已经存在,则会被覆盖。
答案 3 :(得分:0)
如果我需要等待某事,我倾向于使用DoEvents
来允许窗口处理任何其他已被搁置的操作。
从帮助:“产生执行,以便操作系统可以处理其他事件。”
发现这个:
.BeginTrans
然后
.CommitTrans dbForceOSFlush
作为在继续