VBA等待DoCmd.RunSQL或更好的查询-Ms访问
我有一个查询,它使用一个表数组(存储为字符串数组)循环遍历我的表并执行一组删除/更新查询。查询与表名不同,因此使用循环将表名作为变量进行迭代 问题是,我的删除查询锁定了表,更新查询随后运行得太快;我收到一个“db已锁定”错误 我需要两件事中的任何一件:VBA等待DoCmd.RunSQL或更好的查询-Ms访问,sql,ms-access,vba,Sql,Ms Access,Vba,我有一个查询,它使用一个表数组(存储为字符串数组)循环遍历我的表并执行一组删除/更新查询。查询与表名不同,因此使用循环将表名作为变量进行迭代 问题是,我的删除查询锁定了表,更新查询随后运行得太快;我收到一个“db已锁定”错误 我需要两件事中的任何一件: 告诉VBA“等待上一个命令”或 将这些查询连接成一个(或两个)查询的方法:一个用于删除数据库行,另一个用于导入新的行。有了这个,我就可以从一个标准的访问查询运行查询(应该分配适当的时间,完成查询等) 唯一的问题是存在父子关系,因此父表必须在其子表
fromDB
)行,并将其推送到另一个后端的(toDB
)行
编辑:对于有关插入到中的
的问题,我的问题是如果我在toDB
中添加字段,如果我覆盖,它将删除这些字段。我之所以必须使用这种后门方法,是因为数据库仍在开发中,但也在与select表一起使用。每天都会进行更新和功能改进。我也不能使用简单的拆分后端,因为访问数据库的另一台计算机并不总是在网络上(当它返回网络时,我们必须手动同步它),所以我在一个后端上工作,它在另一个相同的(ish,减去我的模式更新)后端上工作。我不是专家,但我认为您不需要删除部分。SELECT INTO是制作表格的语法。如果该表已经存在,它将被覆盖。您可以使用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.beginters
和cnn.CommitTrans
以使这两个语句原子化。如果需要等待,我倾向于使用DoEvents
来允许windows处理已暂停的任何其他操作。
来自帮助:“生成执行,以便操作系统可以处理其他事件。”
找到此:
.begints
然后
.CommitTrans dbForceOSFlush
作为一种在继续之前强制写入更新的方法,请尝试这样做(注意,我已经对您的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
您应该使用CurrentDb.Execute sSQL,dbFailOnError
而不是DoCmd.RunSQL
.Works,我认为这是更好的做法,但我仍然会遇到相同的错误。也许我必须添加一个“wait-until\uuuuuuuuuuu未锁定”改为某种语句?可能是一个新手问题,但VBA无法识别ADODB对象。是否需要在某个位置设置允许此对象?您需要添加对“Microsoft ActiveX数据对象”的引用使用工具->引用。但是您可以考虑尝试<代码> CurrutDB。执行< /COD>作为HK1通配符:基本上说<代码>美国有线电视新闻网< /代码>在您的上面不是有效的OLE DB会话对象。对不起,检查我的编辑应该是“代码> SETVALID= CurrnEngest.CONTION/CODE”。我想是这样的。您的编辑可能是一个PROB。lem,但给出的错误不是问题(我最后的评论)。我认为这与引用有关,因为代码生成器没有将ADODB识别为命令;自动完成上下文菜单没有显示。我添加了引用,重新启动了Access,它发现了.command、.CommandType等。尝试了您的编辑,现在一切正常;无法使用此命令复制我的原始错误方法。似乎很好!即使在使用DoEvents时也会发生相同的错误。是否有原因导致后端被锁定的时间比需要的时间稍长?当然,根据此处建议的所有更改,查询正在完全运行。为什么后端保持锁定?似乎需要刷新缓冲区-我已将信息添加到我的答案中
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