错误:找不到要更新的行。自上次读取以来,某些值可能已更改。关于将提供程序从 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的主要内容,如果未能解决你的问题,请参考以下文章

SQL 窗口函数 - 自上次 Max 以来的行数

选择具有相同值的上次更新的行

自上次更新以来构建失败

在 Flutter SDK 中找不到 Dart

自上次 chrome 更新以来,我的 HTML 输入字段默认为“只读”

Google表格 - 自上次日期以来的天数一系列单元格