使用 OpenQuery 函数在远程表上执行更新、插入或删除 Transact-sql 语句时出现错误消息: "7357" 和 "7320"

症状

使用 OpenQuery 函数以下列方式更新、删除或插入数据的分布式查询

exec sp_dropserver 'linked1', 'droplogins'exec sp_addlinkedserver 'linked1', 'SQL Server'exec sp_setnetname  'linked1', '<servername>'exec sp_addlinkedsrvlogin 'linked1', 'false', null, '<login name>', '<password>'SET ANSI_NULLS ONgoSET ANSI_WARNINGS ONgoselect * from openquery (linked1, 'update testlinked set ssn=ssn+1')select * from openquery (linked1, 'insert into  testlinked  (ssn) values (1000)')select * from openquery (linked1, 'delete from  testlinked  where ssn=1')

可能会生成以下错误消息:

服务器: Msg 7357、Level 16、State 2、第1行无法处理对象 "update testlinked set ssn = ssn"。 OLE DB 访问接口 "SQLOLEDB" 表示该对象没有列。 服务器: Msg 7357、Level 16、State 2、Line 1 [Microsoft] [ODBC SQL Server 驱动程序] [SQL Server] 无法处理对象 "update testlinked set ssn = ssn"。 OLE DB 访问接口 "MSDASQL" 指示该对象没有列。

错误的实际文本消息可能会有所不同,具体取决于 OLE DB 提供程序和正在执行的操作(更新、插入或删除),但错误号始终为7357。 如果您使用的是 Microsoft SQL Server 2005,则会收到以下错误消息:

服务器: Msg 7357、Level 16、State 2、第1行无法处理对象 "update testlinked set ssn = ssn"。 链接服务器 "服务器名称" 的 OLE DB 访问接口 "SQLOLEDB" 表示该对象没有列,或者当前用户没有该对象的权限。

原因

Openquery 需要返回结果集,但更新、删除和插入对 OpenQuery 使用的语句不会返回结果集。

解决方法

你可以通过以下方式解决此问题:

  1. 使用四个部分的名称(linked_server_name catalog object_name)执行插入、更新或删除操作。

  2. 如 SQL Server 联机丛书中所述,请将 OpenQuery 函数作为 INSERT、UPDATE 或 DELETE 语句的目标表进行引用,具体取决于 OLE DB 提供程序的功能。 以下查询使用 SQL Server OLE DB 提供程序演示正确的用法:

    update openquery(linked1, 'select ssn from testlinked where ssn=2')set ssn=ssn + 1insert openquery(linked1, 'select ssn from testlinked where 1=0') values (1000)delete openquery(linked1, 'select ssn from testlinked where ssn>100')

    注意 在 INSERT 语句中,where 1 = 0 谓词用于避免从远程服务器检索数据,这可能会导致性能降低。 此外,更新和删除操作有特殊索引要求;有关详细信息,请参阅 "更多信息" 部分。

更多信息

唯一索引要求

SQL Server OLE DB 提供程序要求更新或删除操作的基础表中存在唯一索引。 如果远程表中不存在唯一索引,则当尝试更新或删除时,将发生以下错误:

服务器: Msg 7320、Level 16、State 2、第1行无法对 OLE DB 访问接口 "SQLOLEDB" 执行查询。 提供程序不支持必需的行查找接口。 提供程序指示与其他属性或要求发生冲突。 [OLE/DB 提供程序返回消息:多步骤 OLE DB 操作生成了错误。 检查每个 OLE DB 状态值(如果可用)。 未完成任何工作。

这两者都适用于 OpenQuery 和由四个部分组成的名为 UPDATE 和 DELETE 操作。 通过在远程表上添加唯一索引来解决此问题。

带有 OpenQuery 的动态执行

有时,可能需要使用动态查询来实现使用 OpenQuery的相同效果,如以下示例所示:

begin tranSET QUOTED_IDENTIFIER OFFSET XACT_ABORT ONdeclare @cmd varchar(2500) declare @cmd1 varchar(2500) declare @var varchar(20) set @var = 'White' declare @var1 varchar(20) set @var1 = 'White1' declare @var2 varchar(20) set @var2 = 'Johnson1'select @cmd = "Update openquery(linked1,'select au_lname, au_fname from pubs.dbo.authorswhere au_lname = ''" + @var + "''' )set au_lname = '" + @var1 + "',au_fname = '" + @var2 + "'"exec ( @cmd )commit transelect * from <servername>.pubs.dbo.authors

需要更多帮助?

扩展你的技能
了解培训
抢先获得新功能
加入 Microsoft 内部人员

此信息是否有帮助?

谢谢您的反馈意见!

×