9

J'essaie d'appeler une fonction définie par l'utilisateur (UDF) sur un serveur lié:SQL Server: Comment appeler une fonction définie par l'utilisateur (UDF) sur un serveur lié?

CREATE FUNCTION [dbo].[UserGroupMembershipNames](@UserGUID uniqueidentifier) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    RETURN ASILIVE.ReportManager.dbo.UserGroupMembershipNames(@UserGUID) 
END 

Cela ne fonctionne pas, comme indiqué dans PRB: User-Defined Function Call in Four-Part Linked Server Query Fails with Error Message 170. Ils donnent également une solution de contournement:

Par exemple, au lieu de la requête suivante

Select * from Linked_Server.northwind.dbo.square_value(10) 

d'exécuter une requête avec la fonction Openquery:

Select * from Openquery(Linked_Server,'select northwind.dbo.square_ value(10)') 

Si la fonction définie par l'utilisateur prend la variable ou les paramètres scalaires, vous pouvez utiliser la procédure stockée sp_executesql pour éviter ce comportement. Par exemple:

exec Linked_Server.northwind.dbo.sp_executesql N'SELECT northwind.dbo.square_value(@input)',N'@input int',@input=10 

Comment puis-je appliquer cette solution à ma situation, et la situation des this guy?

En d'autres termes:

Comment appeler une UDF sur un serveur lié?

Répondre

0
Try the following changes: 

CREATE FUNCTION [dbo].[UserGroupMembershipNames](@UserGUID uniqueidentifier) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    declare @sql nvarchar(800) 
    declare @param nvarchar(20) 
    declare @innersql nvarchar(400) 
    set @param = convert(char(20, @UserGUID) 
    set @innersql = 'select ReportManager.dbo.UserGroupMembershipNames('[email protected]+')' 
    set @sql = 'select * from openquery(ASILIVE,'' '+ @innersql +' '')' 
    RETURN exec sp_executesql @sql 
END 
1

Pour appeler des procédures à distance, vous devez activer RPC OUT sur votre serveur lié. Ouvrez les propriétés du serveur lié dans SSMS puis cliquez sur "Server Option" et assurez-vous que RPC Out est True.

Et ... Votre lien a la solution à votre problème. Regardez la dernière option du WorkAround

« exec Linked_Server.northwind.dbo.sp_executesql N'SELECT northwind.dbo.square_value (@input) », N 'int entrée @', @ entrée = 10"

est ici un test pour vous:

use master 
go 
EXEC master.dbo.sp_addlinkedserver @server = N'(LOCAL)', @srvproduct=N'SQL Server'; 
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'(LOCAL)',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL; 
EXEC master.dbo.sp_serveroption @server=N'(LOCAL)', @optname=N'rpc out', @optvalue=N'true' 
GO 
Use Testing 
GO 
CREATE FUNCTION [dbo].[UserGroupMembershipNames](@UserGUID uniqueidentifier) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    RETURN 'hello' 
END 
GO 
select dbo.[UserGroupMembershipNames]('4278E0BF-2F7A-4D60-A09C-95E517E21EBC') 
GO 
exec [(LOCAL)].Testing.dbo.sp_executesql 
N'select dbo.UserGroupMembershipNames(@UserGUID)',N'@UserGUID uniqueidentifier' 
,@UserGUID='4278E0BF-2F7A-4D60-A09C-95E517E21EBC' 
2

Vérifiez ce lien, qui est mon blog:

http://developersmania.blogspot.com/2012/11/call-user-defined-function-on-linked.html

De simples détails du lien ci-dessus sont la fonction ci-dessous.

CREATE FUNCTION [dbo].Function_Name(@Parameter INT) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 

    DECLARE @word sysname 

    EXEC LinkedServer.DatabaseName.dbo.sp_executesql 
     N'SELECT DatabaseName.dbo.Function_Name(@Parameter)' --dynamic sql query to execute 
     ,N'@Parameter int' --parameter definitions 
     ,@[email protected] OUTPUT --assigning the caller procs local variable to the dynamic parameter 

    RETURN @word 

END 
+1

Merci pour poster votre réponse! Veuillez vous assurer de lire attentivement la [FAQ sur l'autopromotion] (http://stackoverflow.com/faq#promotion). Notez également qu'il est * obligatoire * que vous publiez une clause de non-responsabilité chaque fois que vous créez un lien vers votre propre site/produit. J'ai ajouté dans l'avertissement requis sur ce post. S'il vous plaît ne pas oublier dans le futur. –

+1

En fait, je suis un nouvel utilisateur et d'avoir un problème de duplication de compte au début. Merci pour votre suggestion, je vais prendre soin de cela à l'avenir. –

+1

ne fonctionne pas.Msg 558, niveau 16, état 2, ligne 1 Les appels de fonction à distance ne sont pas autorisés dans une fonction. – Keith

0

Pas la plus jolie solution mais cela fonctionne si vous pouvez contourner le passage de paramètres dans la fonction serveur lié

CREATE FUNCTION fn_LocalFunction 
( 
    @SomeParamOfLinkedFunction VARCHAR(100) 
) 
RETURNS TABLE 
AS 
RETURN 
    SELECT SomeField 
    FROM OPENQUERY([YOURSERVER], 'SELECT * FROM [SOMEDB].dbo.fn_SomeRemoteFunction(NULL)') tst 
    WHERE SomeCondition = @SomeParamOfLinkedFunction