11

我有一组参数需要用不同的参数运行多次,所以我将它包装在一个表值函数中。在SQL Server中远程调用表值函数的解决方法有更多问题

需要从远程服务器调用的那个表值函数。不幸的是,呼叫与错误链接的服务器上失败:

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语法传递一个变量,并且甚至不能连接其中的字符串,如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. 

我不知道为什么我收到此错误,因为映射存在我的用户名,如果我只是用实际的表替换表值函数,它返回的结果罚款。 OPENQUERY语句会出现问题,无论它是否使用sp_executesql执行,正如我所说的,它只在调用表值函数时才会发生。

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

回答

14

你有没有试过这种变化 - 基本上你推调用的函数,在遥控盒本地发生:

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

OPENQUERY已经导致函数在远程服务器上本地运行,并且sp_executesql在本地服务器上运行并不重要,因为无论是否使用sp_executesql执行OPENQUERY都会发生问题。现在它实际上工作正常;问题在于表值函数链接回原始服务器,并且我忘记将远程用户映射添加回链接服务器,而不仅仅是我使用的用户名,如果我在远程服务器上本地运行查询针对链接的本地服务器。 – Triynko

+0

那么在任何情况下,这个语法看起来比打乱OPENQUERY更容易。即使听起来你应该有一个表值函数的本地副本,如果其一半的工作是链接回调用服务器的话...... –

+0

查询链接回去的原因是远程查询必须做一堆左侧加入主服务器上的用户名列表。没有办法将此列表传递给远程服务器,除非远程服务器将其作为链接服务器进行查询。任何其他形式的查询将是复杂或不可靠的,涉及外部连接和合并的用户名字段值。 – Triynko

-1

如果你不能解决它通过调用EXEC(因为你从另一个函数调用这个函数,或者你正在尝试执行像INSERT EXEC这样的操作,但是你不能嵌套它等等),下面是一个解决这个问题的解决方法:

你可以创建一个函数你的本地服务器运行与远程函数相同的查询(假设你知道远程函数的实现),因为你可以访问表和“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 

它应该没有问题。

相关问题