在SQL Server中远程调用表值函数的解决方法存在更多问题

时间:2012-06-11 14:43:14

标签: sql-server-2008 permissions linked-server openquery sp-executesql

我有一组查询需要使用不同的参数多次运行,所以我把它包装在一个表值函数中。

需要从远程服务器调用该表值函数。不幸的是,链接服务器上的调用失败并出现错误:

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

微软承认"远程调用表值函数"是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/

然而,另一个问题是由此造成的。即使在确保所有引号和双引号以及四引号都正确嵌入以便整个事件可以通过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执行,并且正如我所说,只有在调用表值函数时才会出现。

任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:14)

你是否尝试过这种变化 - 基本上你将调用函数推送到远程盒子本地发生:

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

答案 1 :(得分:-1)

如果您无法通过调用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

它应该没有任何问题。