Обходной путь для вызова функции табличной функции удаленно в SQL Server имеет еще больше проблем

У меня был запрос с набором параметров, которые нужно было запускать несколько раз с разными параметрами, поэтому я завернул его в функцию, учитывающую таблицу.

Эта функция, требуемая для таблицы, должна быть вызвана с удаленного сервера. К сожалению, вызов сбоя на связанном сервере с ошибкой:

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, и вы даже не можете конкатенировать в ней строку, например, если вы хотите включить переменные, которые вы хотите передать удаленной табличной функции. Обходной путь для обходного пути заключается в явном построении запроса OPENQUERY с динамическим SQL, обеспечивающего передачу нормальной строки. См.: 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.

Я не уверен, почему я получаю эту ошибку, потому что отображение существует для моего имени пользователя, и если я просто заменю табличную функцию фактической таблицей, она вернет результаты. Проблема возникает с оператором OPENQUERY, независимо от того, выполнялась ли она с помощью sp_executesql или нет, и, как я уже сказал, это происходит только при вызове табличной функции.

Есть идеи, как это решить?

Ответ 1

Пробовали ли вы эту вариацию - в основном вы нажимаете вызов функции, которая должна выполняться локально в удаленном поле:

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

Ответ 2

Если вы не можете решить проблему, вызвав EXEC (потому что вы вызываете эту функцию из другой функции или пытаетесь сделать что-то вроде INSERT EXEC, но вы не можете ее вложить и т.д.), здесь это рабочий стол, который решил эту проблему для меня:

Вы можете создать функцию на своем локальном сервере, которая выполняет тот же запрос, что и удаленная функция (если вы знаете реализацию удаленной функции), поскольку вы можете обращаться к таблицам и "статическим вызовам" (по 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

Он должен работать без проблем.