11

異なるパラメータで複数回実行する必要がある一連のパラメータを持つクエリがあったため、テーブル値関数でラップしました。SQL Serverでテーブル値関数をリモートで呼び出すための回避策がさらに多くの問題を抱えています

テーブル値関数をリモートサーバーから呼び出す必要がありました。残念ながら、呼び出しがエラーでリンクサーバー上の失敗:http://connect.microsoft.com/SQLServer/feedback/details/276758/remote-table-valued-function-calls-are-not-allowed

:Microsoftは、「リモートでテーブル値関数を呼び出す」ことを認めている

Msg 4122, Level 16, State 1, Line 29 
Remote table-valued function calls are not allowed. 

機能は、SQL Serverのうち、2008参照を残しましたOPENQUERY構文を使用して回避策を発見しました。この構文では、リモートサーバー上でクエリをローカルで実行し、結果セットを返すことができます。参照:http://social.msdn.microsoft.com/Forums/en/transactsql/thread/7a6e4aa1-630b-4ad5-aee5-15139987adbd

残念ながら、この回避策では、文字列を引数として使用する必要があります。つまり、OPENQUERY構文を使用して変数を渡すことはできず、ifのように文字列を連結することもできませんリモートテーブル値関数に渡す変数をインクルードする必要があります。回避策の回避策は、動的SQLを使用してOPENQUERYクエリを明示的に作成し、通常の文字列が確実に渡されるようにすることです。参照:http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/0847ad24-0dfe-4ae1-9788-5516c7830f40/

さらに、別の問題が発生します。すべての引用符と二重引用符と四重引用符が正しく埋め込まれているので、すべてがexec sp_executesqlに渡すことができるようにしても問題は残ります。

最終的にクエリでテーブル値関数が呼び出されると、エラー:

OLE DB provider "SQLNCLI10" for linked server "MY_REMOTE_SERVER_NAME" returned message "Deferred prepare could not be completed.". 
Msg 7416, Level 16, State 1, Procedure MyTableValuedFunctionName, Line 22 
Access to the remote server is denied because no login-mapping exists. 

私はマッピングが私の名のために存在しているので、私は、このエラーを取得しています理由はわからないんだけど、私は単純に実際のテーブルとテーブル値関数を交換した場合、それが結果罰金を返します。この問題は、sp_executesqlで実行されているかどうかにかかわらず、OPENQUERY文で発生し、テーブル値関数を呼び出すときにのみ発生します。

これを解決する方法はありますか?

答えて

14

あなたは、このバリエーションを試してみました - 基本的には、リモートボックス上でローカルに発生する関数の呼び出しをプッシュ:あなたがしているので、あなたが(EXECを呼び出すことによってそれを解決することはできません場合は

EXEC REMOTE_SERVER_NAME.db_name..sp_executesql N'SELECT * 
    FROM dbo.MyTableValuedFunctionName();'; 
+0

OPENQUERYは、すでにリモートサーバー上でローカルに実行する機能を引き起こし、問題は、私はとか、sp_executesqlをせずにOPENQUERYを実行するかどうか発生していたので、そのsp_executesqlをローカルサーバー上で実行されていた問題ではありませんでした。実際はうまくいきます。問題は、テーブル値の関数が元のサーバーにリンクし直されていて、リモートサーバー上でクエリをローカルで実行していた場合に使用するユーザー名の代わりに、リモートユーザーマッピングをリンクサーバーに追加するのを忘れていたリンクされたローカルサーバーに対して – Triynko

+0

いずれにしても、この構文はOPENQUERYを使いこなすよりも簡単です。その仕事の半分は、呼び出し元のサーバーにリンクしている場合は、あなたのテーブル値関数のローカルコピーを持っている必要がありますように聞こえるにもかかわらず... –

+0

バッククエリリンク理由は、リモートクエリが束を行わなければならないということですメインサーバー上のユーザー名一覧との左結合のこのリストを、リモートサーバー以外のリモートサーバーに渡してリンクサーバーとして照会する方法はありません。クエリの他の形式は、外部結合および結合されたユーザー名フィールド値を含む複雑または信頼性がありません。 – Triynko

-1

をこの関数を別の関数から呼び出すか、INSERT EXECのような処理をしようとしていますが、入れ子にすることはできません)、ここではこの問題を解決したworkarroundがあります:

(リモート関数の実装を知っていると思いますが)リモートの関数と同じクエリを実行するローカルサーバーは、テーブルと "stati c-called-functions "(openqueryによる)問題なし。あなたは、ローカルサーバ内の関数を作成することができます

CREATE FUNCTION dbo.[remote_function] (@param1 varchar(200)) 
RETURNS TABLE AS RETURN 
(SELECT col1, col2, col3 FROM [remote_db].[dbo].[remote_table] where col1 = @param1) 
GO 

:リモート機能は、このようなものであれば

例では、その後、

CREATE FUNCTION dbo.[local_function] (@param1 varchar(200)) 
RETURNS TABLE AS RETURN 
(SELECT col1, col2, col3 FROM [remote_server].[remote_db].[dbo].[remote_table] where col1 = @param1) 
GO 

そして、あなたが望むようちょうどあなたの新しい機能を問い合わせます...

SELECT col1, col2, col3 FROM dbo.local_function(@param1); 
GO 

問題なく動作するはずです。

関連する問題