2011-11-01 135 views
2

我想运行下面的代码来循环记录集并在需要时进行更新。访问VBA - 运行时错误'3197'

我有一个Microsoft Access数据库连接到MySql后端。每当我运行此代码,我得到了以下错误:

The Microsoft Office Access database engine stopped the process because you and another user are attempting to change the same data at the same time.

的代码如下:

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被更新,然后我得到错误。

回答

4

它似乎没有移动到记录集中的另一条记录。简单递增i不会移至下一条记录。更传统的方法是迭代记录集而不需要其他变量(irsCnt)。

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数据库。 我以前没有在MySQL中使用Access,所以我不知道这是否可行,所以请谨慎操作!

你也可以尝试改变你的记录使用dbOptimistic标志记录锁定选项,看看是否有帮助可言:

set rs = CurrentDB.OpenRecordSet("qryMyQuery", DB_OPEN_DYNASET, dbOptimistic)

+0

很好地完成! + 1 – XIVSolutions

+0

+1就像@XIVSolutions一样,当我收到消息说已经加载了一个新答案时,我写了一个类似的答案。 – mwolfe02

+0

另外,纠正我,如果我错了,但我相信rs.Edit必须进入循环。从DAO帮助文件中:**编辑方法:** *将可更新记录集对象的**当前记录**复制到复制缓冲区以供后续编辑。* – mwolfe02

1

我没有的MySQL在这里尝试这种打击,但它在我看来好像你的代码没有在rs.Update方法执行后推进记录集,所以你试图在fierst记录中更新相同的字段。

添加此行的rs.Update后:

rs.MoveNext 

希望有所帮助。

+0

此外,Tim Lentine发布的代码是一种更优雅的方式。他在我还在写我的答案时发帖。 – XIVSolutions

+1

如果人们要冷静下来,如果他们会用一些推理来支持投票,那就太好了。只是说' – XIVSolutions

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上的操作可以直接引发关于“未设置块”的错误。但是,当使用对象变量时,我不会收到错误。 ISTR OpenRecordset就是这样一个问题。

而且,我的印象是你的方法是实现的相当于麻烦的方式:

UPDATE qryMyQuery SET FieldNameHere = "test"; 

不过,我怀疑的例子是对现实世界的情况,其中记录的方法是有用的代理。这仍然让我怀疑在执行UPDATE语句时是否会看到相同或不同的错误。

如果您仍然遇到此问题,可能有助于向我们展示qryMyQuery的SQL视图。

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 
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表,但没能帮助新记录数据时,和旧的一样。

+0

我也经历过相同的。在这个MySQL错误报告中提到:http://bugs.mysql.com/bug.php?id=46406 这似乎是由Access的形式更新查询的方式造成的。它可以像你建议的客户端或服务器端使用'timestamp'列来解决。 – AronVanAmmers

0

我的一点有用的提示是,在将SQL表链接到Microsoft Access时要使用的数据类型非常非常非常糟糕,因为只有SQL Server能够理解这个位是什么,Microsoft Access很难解释这个位是什么。将任何位数据类型更改为int(整数),并重新链接应清除事务的表。另外,请确保您的布尔值在您的VBA代码中始终包含1或0(不是yes/no或true/flase),否则您的更新将无法连接到SQL表格,因为Microsoft Access会尝试使用True/False或是/否,SQL不会那样。

0

我也有同样的问题;我解决了他们使用dao.recordset添加这些代码:

**rst.lockedits = true** 
rst.edit 
rst.fields(...).value = 1/rst!... = 1 
rst.update 
**rst.lockedits = false** 

这似乎是解决刚开业数据之间的冲突(如表格),并与代码更新它们。

对不起我的英语不好......我读了很多,但我从来没有学过它!我只是意大利人。

+0

如果您已将代码更改为SQL语句,请注意。 Form_Unload事件尝试更新您通过SQL更改的相同数据并引发不可管理的错误;这可以消除所有的应用程序。 – AntonioFico