2009-02-27 11 views
4

私はMicrosoft SQL Server 2005を使用しています。SQL ServerとOracleデータベース間でデータを同期する必要があります。私が必要とする最初の事は、特定のフィルタ(ここで私は単純な例としてIDを使用して)とOracle側のデータの数を調べることです。EX linked server AT linked servers Oracleデータベース

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

私が問題にしているのは、サーバーまたはOracleの並んでいるテーブルが4M行のデータで非常に大きいことです。上記のクエリは、データを取得するのに約2分かかりました。このコードは単なる単純なものです。実際に私のSPには、更新するいくつかの他のクエリがあり、並べ替え済みのサーバからSQLサーバにデータを挿入します。大規模なOracleデータベースを使用するには、SPに数時間または10時間以上かかることがありました。したがって、サーバーが並んでいる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(*)を戻す方法です。私はwebとmsdnでgoogleの例を試しました。私が見つけることができるのは、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パラメータとして値を渡す方法があるかどうか疑問に思っています。その結果、私のSPにより良いパフォーマンスのT-SQLコードを置くことができますか?

答えて

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

より10速い^多くは最近、私はこの方法では1、興味深い問題を発見しました。私はExec()を使って詳細を掲載しました(続き)(http://davidchuprogramming.blogspot.com/2009/03/using-exec-at-continued.html)。 –

0

最大の問題は、パフォーマンスが [linkedserver]...[dbo.RemoteTable] vs OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')はいつも疑問に答えるために今

秒1を使用します(私見)です。 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') 

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