9

Sto cercando di chiamare una funzione definita dall'utente (UDF) in un server collegato:SQL Server: come chiamare una funzione definita dall'utente (UDF) sul server collegato?

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

Questo non funziona, come documentato in PRB: User-Defined Function Call in Four-Part Linked Server Query Fails with Error Message 170. Danno anche una soluzione:

Ad esempio, invece che la seguente query

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

Eseguire una query con la funzione Openquery:

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

Se la funzione definita dall'utente prende variabile o i parametri scalari, è possibile utilizzare la stored procedure sp_executesql per evitare questo comportamento. Per esempio:

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

Come potrei applicare questa soluzione alternativa per la mia situazione, e la situazione di this guy?

In altre parole:

Come chiamare una funzione definita dall'utente in un server collegato?

risposta

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

Per chiamare procedure remote, è necessario attivare RPC OUT sul server collegato. Apri le Proprietà del server collegato in SSMS, quindi fai clic su "Opzione server" e assicurati che RPC Out sia True.

E ... Il tuo link ha la soluzione al tuo problema. Guardate l'ultima opzione nella soluzione alternativa

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

Ecco un banco di prova per voi:

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

controllare questo link, che è il mio blog:

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

I dettagli semplici del link precedente sono la funzione seguente.

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

Grazie per pubblicare la tua risposta! Si prega di leggere attentamente le [FAQ sulla promozione di sé] (http://stackoverflow.com/faq#promotion) attentamente. Si noti inoltre che * è * richiesto * di pubblicare un disclaimer ogni volta che si collega al proprio sito/prodotto. Ho aggiunto il disclaimer richiesto su questo post. Per favore non dimenticare in futuro. –

+1

In realtà sono un nuovo utente e ho inizialmente un problema di duplicazione dell'account. Grazie per il tuo suggerimento, mi prenderò cura di questo in futuro. –

+1

non funziona.Messaggio 558, livello 16, stato 2, riga 1 Le chiamate di funzione remote non sono consentite all'interno di una funzione. – Keith

0
Non

la soluzione più bella ma funziona se è possibile aggirare i parametri di passaggio nella funzione di server collegato

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