2010-03-03 55 views
6

我正在編寫一個腳本,該腳本應該運行在一堆服務器上,並從中選擇一堆數據,包括本地服務器。選擇我需要的數據所需的SQL非常複雜,所以我正在編寫某種特定視圖,並使用OPENQUERY語句來獲取數據,因此最終我最終會循環顯示如下所示的語句:爲什麼在本地服務器上使用OPENQUERY不好?

exec('INSERT INTO tabl SELECT * FROM OPENQUERY(@Server, @AdHocView)') 

但是,我聽說在本地服務器上使用OPENQUERY是皺眉。有人可以詳細說明爲什麼嗎?

+0

這是一個adminstirative腳本,所以我不擔心權限。 我的問題,特別是當腳本遍歷服務器列表並運行到它自己的服務器名稱時,有什麼問題嗎?這通常會引發錯誤,服務器未配置爲數據訪問,可通過 EXEC sp_serveroption'LocalServer','DATA ACCESS',TRUE – Dlongnecker 2010-03-03 21:11:25

+0

檢查[鏈接的服務器](http://msdn.microsoft.com/zh-cn/我們/庫/ ms188279。aspx) – Andrey 2010-03-03 20:43:24

回答

6
  • 儘管查詢可能會返回多個結果集,但OPENQUERY僅返回第一個結果集。
  • OPENQUERY不接受其參數的變量。
  • OPENQUERY不能用於在鏈接服務器上執行擴展存儲過程。但是,擴展存儲過程可以通過使用四部分名稱在鏈接的服務器上執行。
  • 如果sp_addlinkedserver存儲過程是相同的腳本中使用,在遠程服務器上使用的憑據硬編碼到腳本,可見於任何人誰擁有一個拷貝

參考:

+0

我偶然有機會在前些日子使用'OPENQUERY',並意識到你的第四點是不正確的; 'OPENQUERY'在鏈接服務器上運行,所以沒有憑證是硬編碼的。你可能會想到'OPENROWSET'。 – Aaronaught 2010-03-07 15:22:46

+0

@Aaronaught:如果存在鏈接的服務器實例,爲什麼要使用OPENQUERY?如果在同一個腳本中使用'sp_addlinkedserver'存儲過程,我的觀點就有價值。 – 2010-03-07 23:03:21

+1

那麼,既然你問,實際上有一個原因使用'OPENQUERY':性能。 'OPENQUERY'允許在遠程服務器上處理查詢,而標準的4部分命名必須將所有行復制到本地服務器,這對於大型數據集來說是相當糟糕的。當然,這必須與你提到的其他權衡權衡。 – Aaronaught 2010-03-08 01:02:30

2

除了@OMG Ponies所說的,這根本就沒有必要。沒有必要的時候沒有理由引入臨時查詢和分佈式事務語義。當您使用OPENQUERY時,您將承擔動態SQL的所有負面影響,包括較少可預測的計劃和服務器無法準確跟蹤依賴關係。

OPENQUERY還要求本地用戶擁有目標服務器的權限,這可能不是您想要的,除非它是管理腳本。您不能指望每個數據庫的每個用戶對每個其他數據庫擁有相同的權限。

2

只是後續。

OpenQuery是很好的,當你必須比較或操縱存儲過程的一些行集。

例如,如果你有,當你從SQL Server遷移到比較來自兩個服務器成績(測試和部署服務器)2005SQL Server 2008的例如,那麼你可以做下面的查詢:

select * into test_table from OpenQuery(testServer, 'exec testdb.dbo.test_sp'); 
select * into rollout_table from OpenQuery(rolloutServer, 'exec testdb.dbo.test_sp'); 

select * from test_table 
except 
select * from rollout_table; 

select * from rollout_table 
except 
select * from test_table; 

看到任何差異。

相關問題