11

que tuve una consulta con un conjunto de parámetros que debían ser ejecutado varias veces con diferentes parámetros, por lo que lo envolvió en una función con valores de tabla.Solución para llamar a la función con valores de tabla remota en SQL Server tiene incluso más problemas

Esa tabla de función valorada necesitaba llama desde un servidor remoto. Por desgracia, la llamada falla en el servidor vinculado con el error:

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

Microsoft ha reconocido que "llamar a una función con valores de tabla remota" era una característica dejado fuera de SQL Server 2008. Véase: http://connect.microsoft.com/SQLServer/feedback/details/276758/remote-table-valued-function-calls-are-not-allowed

Descubrí una solución utilizando la sintaxis OPENQUERY, que permite que la consulta se ejecute localmente en el servidor remoto y luego devuelva el conjunto de resultados. Ver: http://social.msdn.microsoft.com/Forums/en/transactsql/thread/7a6e4aa1-630b-4ad5-aee5-15139987adbd

Desafortunadamente, esta solución alternativa necesitaba una solución, porque requiere una cadena como argumento, lo que significa que no puede pasar una variable con la sintaxis OPENQUERY y no puede concatenar una cadena, como desea incluir variables que desea pasar a la función de valor de tabla remota. La solución para la solución temporal es crear explícitamente la consulta OPENQUERY con SQL dinámico, asegurando que se le pase una cadena normal. Ver: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/0847ad24-0dfe-4ae1-9788-5516c7830f40/

Sin embargo, otro problema es consecuencia de esto. Incluso después de asegurarse de que todas las comillas, comillas dobles y comillas cuádruples estén incrustadas correctamente para que todo se pueda pasar a través de exec sp_executesql, todavía hay un problema:

Cuando la consulta finalmente llama a la función con valores de tabla, obtengo de error:

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. 

no estoy seguro de por qué estoy recibiendo este error, ya que existe la asignación de mi nombre de usuario, y si simplemente reemplazar la función con valores de tabla con una tabla real, devuelve los resultados fina . El problema ocurre con la instrucción OPENQUERY, independientemente de si se ejecuta con sp_executesql o no, y como dije, solo ocurre cuando se llama a una función con valores de tabla.

Alguna idea de cómo solucionar esto?

Respuesta

14

Ha intentado esta variación - básicamente se presiona la llamada a la función que suceda de forma local en el cuadro de mando a distancia:

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

OPENQUERY ya causa que la función se ejecute localmente en el servidor remoto, y no importaba que sp_executesql se ejecutara en el servidor local, porque el problema era que ocurría si ejecutaba OPENQUERY con o sin sp_executesql. En realidad funciona bien ahora; el problema era que la función de valor de tabla se vinculaba al servidor original, y olvidé agregar la asignación de usuarios remotos al servidor vinculado en lugar de solo mi nombre de usuario que usaría si ejecutara una consulta localmente en el servidor remoto contra el servidor local vinculado. – Triynko

+0

Bueno, en cualquier caso, esta sintaxis parece más fácil que jugar con OPENQUERY. Aunque parece que debería tener una copia local de su función con valores de tabla si la mitad de su trabajo es vincular al servidor de llamadas ... –

+0

La razón por la que la consulta vincula es que la consulta remota tiene que hacer un montón de la izquierda se une a una lista de nombres de usuario en el servidor principal. No hay forma de pasar esta lista al servidor remoto que no sea para que el servidor remoto lo busque como un servidor vinculado. Cualquier otra forma de la consulta sería compleja o poco confiable, lo que implicaba uniones externas y valores de campo de nombre de usuario fusionados. – Triynko

-1

En caso de que no puede resolverlo llamando a un EXEC (porque eres llamando a esta función desde otra función o estás intentando hacer algo como INSERTAR EXEC pero no puedes anidarlo, etc.), aquí hay un workarround que resolvió este problema para mí:

Puedes crear una función en su servidor local que ejecuta la misma consulta que la función remota (asumiendo que conoce la implementación de la función remota) ya que puede acceder a tablas y "stati" c-called-functions "(por openquery) sin problemas.

En el ejemplo, si la función de control remoto es algo como esto:

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 

Puede crear una función en el servidor local:

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 

Y luego simplemente consultar su nueva función como desee ...

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

Debería funcionar sin problemas.

Cuestiones relacionadas