web-dev-qa-db-ja.com

SQLServerでテーブル値関数をリモートで呼び出すための回避策にはさらに多くの問題があります

さまざまなパラメーターを使用して複数回実行する必要がある一連のパラメーターを含むクエリがあったため、テーブル値関数でラップしました。

そのテーブル値関数は、リモートサーバーから呼び出される必要がありました。残念ながら、リンクサーバーでの呼び出しは次のエラーで失敗します。

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

Microsoftは、「テーブル値関数をリモートで呼び出す」ことがSQL Server 2008から除外された機能であることを認めています。参照: http://connect.Microsoft.com/SQLServer/feedback/details/276758/remote-table -valued-function-calls-are-not-allowed

OPENQUERY構文を使用した回避策を発見しました。これにより、クエリをリモートサーバーでローカルに実行し、結果セットを返すことができます。参照: http://social.msdn.Microsoft.com/Forums/en/transactsql/thread/7a6e4aa1-630b-4ad5-aee5-15139987adbd

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

それでも、これには別の問題があります。すべての引用符、二重引用符、および4重引用符が正しく埋め込まれていることを確認した後でも、すべてを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ステートメントで発生します。前述したように、この問題はテーブル値関数を呼び出すときにのみ発生します。

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

12
Triynko

このバリエーションを試しましたか?基本的に、関数の呼び出しをプッシュして、リモートボックスでローカルに実行します。

EXEC REMOTE_SERVER_NAME.db_name..sp_executesql N'SELECT * 
  FROM dbo.MyTableValuedFunctionName();';
14
Aaron Bertrand