错误:找不到要更新的行。自上次读取以来,某些值可能已更改。关于将提供程序从 SQLOLEDB 更改为 MSOLEDBSQL
Posted
技术标签:
【中文标题】错误:找不到要更新的行。自上次读取以来,某些值可能已更改。关于将提供程序从 SQLOLEDB 更改为 MSOLEDBSQL【英文标题】:Error: Row cannot be located for updating. Some values may have been changed since it was last read. On changing provider from SQLOLEDB to MSOLEDBSQL 【发布时间】:2022-01-13 05:53:29 【问题描述】:在 ADODB 连接字符串中将提供程序从 SQLOLEDB 更改为 MSOLEDBSQL 时,我们收到错误:
-2147217864 无法找到要更新的行。自上次读取以来,某些值可能已更改。
连接字符串为:
Provider=MSOLEDBSQL;SERVER=servername;APP=Applicationname;DATABASE=databasename;WSID=id;Trusted_Connection=yes;MARS Connection=True;DataTypeCompatibility=80
代码如下:
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open("SELECT * FROM tableName WHERE 1 = 2", Adoconnection, adOpenStatic, adLockBatchOptimistic, CommandTypeEnum.adCmdText)
rs.AddNew
'Add the fields
...
...
rs.UpdateBatch ''this line throws error
现在,当提供者的连接字符串更改为 SQLOLEDB 时,使用相同的代码,它可以正常工作,没有任何问题。
【问题讨论】:
那为什么要使用 MSOLEDBSQL? 正如微软所说,“SQLOLEDB 不再维护,不建议在新开发中使用此驱动程序。”和 MSOLEDBSQL,提供安全更新、数据类型兼容性、mars 功能等 【参考方案1】:尝试在表中添加时间戳或所谓的“rowversion”列。 (使用类型时间戳 - 与时间有关的为零)。
此外,如果该表中有任何位列,请确保它们不为空,并确保为该位列设置默认值 (0)。
如果应用程序具有链接表,则在您进行上述更改服务器端后重新链接您的表。
【讨论】:
我们已经有了时间戳或所谓的“行版本”列:) 并且所有位列都没有空值,都有默认值。 如果这是从表单调用的,那么在上面的代码之前执行一个 me.Dirty = false 然后运行你的代码。【参考方案2】:我发现了问题,是在 SQL 触发器中。
相应的表在触发器上有一些更新语句。在触发器中的更新语句之前添加SET NOCOUNT ON
帮助我避免了这个错误。
【讨论】:
以上是关于错误:找不到要更新的行。自上次读取以来,某些值可能已更改。关于将提供程序从 SQLOLEDB 更改为 MSOLEDBSQL的主要内容,如果未能解决你的问题,请参考以下文章