1

我有一个查询,它使用一组表(存储为字符串数组)来循环我的表并执行一组删除/更新查询。除了表名之外,查询是相同的,因此使用循环来迭代使用表名作为变量。

问题是,我的删除查询锁定了表,之后更新查询运行得太快了;我收到“数据库已锁定”错误。

我需要两件事之一:

  1. 一种告诉 VBA“等待上一个命令”的方法或
  2. 一种将这些查询连接成一个(或两个)查询的方法:一个用于删除数据库行,另一个用于导入新行。有了这个,我可以从标准访问查询中运行查询(应该分配适当的时间,完成查询等)

唯一的问题是存在父子关系,因此父表必须在其子表之前更新(目前通过数组排序完成)。

这是(有时)产生“数据库锁定/正在使用”消息的当前代码:

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,如果我覆盖,它将删除它们。我必须使用这种后门方法的原因是因为数据库仍在开发中,但也与选择表一起使用。每天都会进行更新和功能改进。我也不能使用简单的拆分后端,因为访问数据库的另一台计算机并不总是在网络上(当它返回网络时我们必须手动同步它),所以我在一个后端工作,它在另一个后端工作,相同(ish,减去我的架构更新)后端。

4

4 回答 4

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.BeginTranscnn.CommitTrans使这两个语句成为原子的。

于 2012-06-07T14:55:19.767 回答
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
于 2021-02-14T19:27:31.027 回答
0

我不是专家,但我认为您不需要 DELETE 部分。SELECT INTO 是制作表格的语法。如果表已存在,则将其覆盖。

于 2012-06-07T14:05:27.140 回答
0

如果我需要等待某事,我倾向于使用DoEvents允许 Windows 处理已暂停的任何其他操作。
来自帮助:“产生执行,以便操作系统可以处理其他事件。”

发现这个:
.BeginTrans然后
.CommitTrans dbForceOSFlush
作为一种在继续之前强制写入更新的方法

于 2012-06-07T15:16:51.907 回答