使用 OpenQuery 函式對遠端表執行DML

fanhongjie發表於2008-04-24

SQL SERVER

當透過使用 OpenQuery 函式對遠端表執行 UPDATE、 INSERT, 或 DELETETransact-SQL 語句錯誤訊息: " 7357 " 和 " 7320 "

[@more@]

症狀

分散式查詢, 使用 OpenQuery 函式來更新、 刪除, 或以下列方式插入資料
exec sp_dropserver 'linked1', 'droplogins'
exec sp_addlinkedserver 'linked1', 'SQL Server'
exec sp_setnetname  'linked1', ''
exec sp_addlinkedsrvlogin 'linked1', 'false', null, '', ''

SET ANSI_NULLS ON
go
SET ANSI_WARNINGS ON
go
select * 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')
可能生成以下錯誤資訊: 
伺服器: 訊息 7357, 16, 級別狀態 2, 行 1 可能不處理物件 = ssn 更新 testlinked 設定 ssn ' '。 OLEDB 提供程式 ' SQLOLEDB ' 指出物件具有任何列。

伺服器: 訊息 7357, 16, 級別狀態 2, 行 1 [ Microsoft SQL Server 驅動程式 ] [ SQLServer ] [ ODBC ] 可能不處理物件 = ssn 更新 testlinked 設定 ssn ' '。 OLEDB 提供程式 ' ' MSDASQL 表明物件已經沒有列。
對錯誤實際文字訊息可能有所不同根據 OLEDB 提供程式和操作 (UPDATE、 INSERT 或 DELETE) 執行, 但錯誤號總是 7357。

如果您使用 Microsoft SQL Server 2005, 您會收到以下錯誤資訊:
伺服器: 訊息 7357, 16, 級別狀態 2, 行 1 無法處理物件 = ssn 更新 testlinked 設定 ssn " "。 OLEDB 提供程式 " SQLOLEDB " 為連結伺服器 " ServerName " 表明該物件沒有任何列或者當前使用者對該物件沒有許可權。

原因

OpenQuery 要求一個結果集要返回, 但不返回結果集 UPDATE、 DELETE 和 INSERT 語句與 OpenQuery 一起使用。

替代方法

按如下方法您可以解決此問題:
1.使用四部分名稱 (linked_server_name.catalog.schema.object_name) 來執行插入、 更新, 或刪除操作。
2.SQLServer 聯機叢書中所述引用 OpenQuery 函式作為目標表是 INSERT, UPDATE, 或 DELETE 語句, 受到 OLEDB 提供程式的能力。 下列查詢說明正確用法與 SQLServerOLEDB 提供程式:
update openquery(linked1, 'select ssn from testlinked where ssn=2')
set ssn=ssn + 1
insert openquery(linked1, 'select ssn from testlinked where 1=0') values (1000)
delete openquery(linked1, 'select ssn from testlinked where ssn>100')
						
注意 對於將 INSERT 語句, 其中 1 = 0 謂詞用於避免從遠端伺服器, 這會導致效能下降檢索資料。 還, UPDATE 和 DELETE 操作具有特殊索引要求 ; 請參閱 " 更多資訊 " 部分詳細。

更多資訊

唯一索引要求

SQLServerOLEDB 提供程式要求基礎表用於 UPDATE 或 DELETE 操作上存在唯一索引。 如果沒有唯一索引, 遠端表上存在試圖 UPDATE 或 DELETE 時發生錯誤:
對 OLEDB 提供程式 ' SQLOLEDB ' 伺服器: 訊息 7320, Level 16, 狀態 2, Line 1 可能不執行查詢。 提供程式未能支援必需行查詢介面。 提供程式指出與其它屬性或要求發生衝突。 [: 多步驟 OLEDB 操作產生錯誤 / OLE DB 提供程式返回訊息。 如果可用檢查每個 OLEDB 狀態值。 沒有工作已完成。
如此要 OpenQuery 和四部分命名 UPDATE 和 DELETE 操作。 透過遠端表上新增一個唯一索引解決此問題。

使用 OpenQuery 動態執行

有時可能需要使用動態查詢來獲得同樣效果使用 OpenQuery , 如以下示例所示:
begin tran
SET QUOTED_IDENTIFIER OFF
SET XACT_ABORT ON
declare @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.authors
where au_lname = ''" + @var + "''' )
set au_lname = '" + @var1 + "',
au_fname = '" + @var2 + "'"

exec ( @cmd )

commit tran
select * from .pubs.dbo.authors

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/73920/viewspace-1002938/,如需轉載,請註明出處,否則將追究法律責任。

相關文章