我正在尝试运行以下代码来循环记录集并在必要时进行更新。
我有一个连接到MySql后端的Microsoft Access数据库。每当我运行此代码时,我都会收到以下错误:
Microsoft Office Access数据库引擎已停止该过程,因为您和另一个用户正在尝试同时更改相同的数据。
代码如下:
Private Sub test()
Dim rs As DAO.Recordset, rsCnt As Long, i As Long
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
rs.MoveLast
rsCnt = rs.RecordCount
rs.MoveFirst
For i = 1 To rsCnt
rs.Edit
rs!MyFieldInTable = "test"
rs.Update
Next i
End Sub
我认为Access数据库可能已损坏所以我提取了一个早期的备份,但是它做了同样的事情,这让我觉得这是一个MySql问题。
我们在链接到不同MySql表的此数据库的另一个版本上使用相同的代码,它可以正常工作。
另外,当我打开查询时,记录集基于我可以编辑查询中的数据而没有任何问题。
只需添加,在第一个循环中,rs!MyFieldInTable被更新,然后我收到错误。
答案 0 :(得分:4)
您似乎没有移动到记录集中的另一条记录。简单地递增i
不会移动到下一条记录。更传统的方法是迭代记录集而不需要其他变量(i
和rsCnt
)。
Dim rs as DAO.Recordset
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
rs.moveFirst
Do Until rs.EOF
rs.Edit
rs!FieldNameHere = "test"
rs.Update
rs.MoveNext
Loop
修改强> 经过一番搜索,我遇到了this thread这似乎与您的问题类似。在线程的底部,建议通过选择“高级”选项卡并选择“返回匹配行”选项来修改MySQL DSN的ODBC设置。该帖子还说要删除链接表,然后将其重新链接到Access数据库。 我以前没有使用Access和MySQL,所以我不知道这是否有效,所以请谨慎行事!
你也可以尝试更改你的记录集,使用dbOptimistic标志来记录集锁定选项,看看它是否有帮助:
set rs = CurrentDB.OpenRecordSet("qryMyQuery", DB_OPEN_DYNASET, dbOptimistic)
答案 1 :(得分:2)
你可以尝试两件事。首先,尝试在打开记录集时添加dbSeeChanges选项:
Dim rs as DAO.Recordset, db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryMyQuery", dbOpenDynaset, dbSeeChanges)
Do Until rs.EOF
rs.Edit
rs!FieldNameHere = "test"
rs.Update
rs.MoveNext
Loop
正如@HansUp建议的那样,另一个选项是使用SQL更新语句而不是动态记录集。关键是打开记录集作为快照,这样您对记录所做的更改不会影响记录集本身。
Dim rs as DAO.Recordset, db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryBatchPayments", dbOpenSnapshot)
Do Until rs.EOF
db.Execute "UPDATE Payments " & _
"SET DCReference='test' " & _
"WHERE PaymentID=" & !PaymentID, dbFailOnError
rs.MoveNext
Loop
答案 2 :(得分:2)
我遇到了同样的问题,我的解决方案被证明是BIT(1)字段的默认值。 Access不希望这些为null。确保在mysql中对这些字段使用0或1。
答案 3 :(得分:1)
我没有MySQL在这里试试这个,但它看起来好像你的代码在rs.Update方法执行后没有推进记录集,所以你试图在相同的字段中使用fierst记录。
在rs.Update:
之后添加此行rs.MoveNext
希望有所帮助。
答案 4 :(得分:1)
尝试从设置为CurrentDb()的对象变量调用OpenRecordset,而不是直接从CurrentDb()调用。
Dim rs as DAO.Recordset
Dim db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
rs.moveFirst
Do Until rs.EOF
rs.Edit
rs!FieldNameHere = "test"
rs.Update
rs.MoveNext
Loop
该建议的原因是我发现直接对CurrentDb的操作可能会抛出“block not set”的错误。但是在使用对象变量时我没有得到错误。 ISTR OpenRecordset是一个这样的操作,这是一个问题。
另外,我的印象是你的方法是一种繁琐的方法来实现相当于:
UPDATE qryMyQuery SET FieldNameHere = "test";
但是,我怀疑该示例是记录集方法有用的真实世界情况的代理。仍然这让我想知道在执行UPDATE语句时是否会看到相同或不同的错误。
如果您仍然遇到此问题,可能有助于向我们展示qryMyQuery的SQL视图。
答案 5 :(得分:0)
我发现如果试图保存与MySql记录中已有的数据相同的数据Access将显示此类错误。我已尝试过这个帖子的一些建议,但没有帮助。
对此的简单解决方案是使用手动时间戳保存稍微不同的数据。这是一个提升排序顺序字段并将其设置为10,20,30 ......
的示例 i = 10
timeStamp = Now()
Do Until Employee.EOF
Employee.Edit
Employee!SortOrderDefault = i
Employee!LastUpdated = timeStamp
Employee.Update
i = i + 10
Employee.MoveNext
Loop
我在MySql表中尝试过自动时间戳,但在新条目数据与旧条目数据相同时没有帮助。
答案 6 :(得分:0)
我的一点点有用的提示是,在将SQL表链接到Microsoft Access时要使用的数据类型是非常非常非常糟糕的,因为只有SQL Server能够理解它的含义,Microsoft Access很难解释它的含义。将任何位数据类型更改为int(整数)并重新链接应清除的表。此外,确保您的布尔值在您的VBA代码中始终包含1或0(不是是/否或真/ / flase),否则您的更新将无法链接到SQL表,因为Microsoft Access将尝试使用True更新它们/ False或是/否和SQL不会那样。
答案 7 :(得分:0)
我也有同样的问题;我解决了他们使用dao.recordset将代码添加到代码中:
**rst.lockedits = true**
rst.edit
rst.fields(...).value = 1 / rst!... = 1
rst.update
**rst.lockedits = false**
这似乎解决了刚打开的数据(例如表单中)和用代码更新它们之间的冲突。
抱歉我的英语不好......我读了很多但我从未学过它!我只是意大利人。