2009-02-27 26 views
4

我正在使用Microsoft SQL Server 2005.我需要在SQL Server和Oracle數據庫之間同步數據。我需要的第一件事是找出是否有某些過濾器(這裏我使用ID作爲一個簡單的例子)的Oracle端數據的計數。EXEC(查詢)AT linkedServer與Oracle DB

SELECT COUNT(*) FROM oracleServer..owner.table1 WHERE id = @id; 

我遇到的問題是,內襯服務器或Oracle上的表格非常大,有4M行數據。上面的查詢需要大約2分鐘才能獲取數據。這段代碼只是一個簡單的部分。其實我的SP有一些其他的查詢來更新,插入數據從內襯服務器到我的SQL服務器。 SP需要幾個小時或10個小時才能運行大型Oracle數據庫。因此,帶有內襯服務器的T-SQL對我並不好。

最近我發現OPENQUERY和EXEC(...)AT linedServer。 OPENQUERY()非常快。花費大約0次才能得到相同的結果。但是,它不支持變量查詢或表達式。查詢必須是文字常量字符串。

EXEC()與傳遞查詢到Oracle的方式相同。它也很快。例如:

EXEC ('SELECT COUNT(*) FROM owner.table1 WHERE id = ' + CAST(@id AS VARCHAR)) 
    AT oracleServer 

我遇到的問題是如何將結果COUNT(*)返回。我試圖在谷歌和MSDN的谷歌示例。我只能找到SQL或ExpressSQL linedServer示例,如:

EXEC ('SELECT ? = COUNT(*) FROM ...', @myCount OUTPUT) AT expressSQL 

此查詢不適用於Oracle。這似乎在Oracle中,你可以設置值爲這樣的輸出:

SELECT COUNT(*) INTO myCount ... 

我嘗試這樣:那些工作的

EXEC ('SELECT COUNT(*) INTO ? FROM ...', @myCount OUTPUT) AT oracleServer 
EXEC ('SELECT COUNT(*) INTO : FROM ...', @myCount OUTPUT) AT oracleServer 
EXEC ('SELECT : = COUNT(*) FROM ...', @myCount OUTPUT) AT oracleServer 

無。我收到錯誤消息說在Oracle服務器上查詢不可執行。

我可以編寫一個.Net SQL Server項目來完成這項工作。在此之前,我只是想知道是否有辦法將值作爲oupput參數傳遞出去,以便將更好的性能T-SQL代碼放在我的SP中?

回答

3

只是在此快速更新。我想我得到了解決方案。我在Dev NewsGroup的類似問題的討論中發現它。根據這些信息,我試過這個:

DECLARE @myCount int; 
DECLARE @sql nvarchar(max); 
set @sql = 
N'BEGIN 
    select count(*) into :myCount from DATAPARC.CTC_MANUAL_DATA; 
END;' 
EXEC (@sql, @myCount OUTPUT) AT oracleServer; 
PRINT @myCount; -- 3393065 

哇!我比較直接在Orable DB(+ 2分鐘)上比較T-SQL查詢,在3秒內得到結果。重要的是使用「BEGIN」和「END」將查詢包裝爲匿名塊並且不要錯過「;」結束後

您需要輸出參數的匿名塊。如果你只有輸入或沒有參數,你不需要塊,查詢工作正常。

享受它!順便說一句,這是一個快速更新。如果你沒有再看到我,我在這個問題上不會遇到任何麻煩。

+1

更快最近我發現用這種方法一個有趣的問題。我在使用Exec()繼續(http://davidchuprogramming.blogspot.com/2009/03/using-exec-at-continued.html)上發佈了詳細信息。 – 2009-03-07 20:58:36

0

使用鏈接服務的最大的問題是性能(恕我直言) [linkedserver]...[dbo.RemoteTable] vs OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')總是使用第二個

我們回答這個問題。 OPENQUERYEXEC() AT要快得多。 EXEC(Select * from dbo.RemoteTable) AT linkedserver會顯示結果,但是沒有辦法重新使用。

我簡單的解決方案:

SELECT * INTO LocalTable FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable') 

OR

INSERT INTO LocalTable SELECT * FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable') 

多^ 10比

SELECT * INTO LocalTable FROM [linkedserver]...[dbo.RemoteTable]