2013-07-12 6 views
0

У меня хранимая процедура SprocA находится на сервере ServerA. SprocA принимает 4 параметра, выполняет динамический sql и возвращает запись с 1 столбец (1 целочисленное значение). Я хотел бы иметь возможность вызвать это из функции FnB на ServerB, чтобы я мог использовать ее в хранимой процедуре SprocB на сервере ServerB, чтобы вернуть набор записей.вызов удаленного sproc из функции

Например, я хотел бы иметь что-то вроде этого

Create Function FnB 
    @CustomerId int 
    ,@PartId  varchar(30) 
    ,@DateFrom datetime 
    ,@DateTo  datetime 
    Returns int 
As 
Begin 

    Declare @Ret int 
    Exec @Ret = LnkSrv.DB_History.dbo.SprocA(@CustomerId, @PartId, @DateFrom, @DateTo) 

    Return @Ret 
End --FnB 


Create Procedure SprocB 
    @RowId int 
As 
Begin 

    Select Partid, FnB(Customerid, Partid, DateFrom, DateTo) As TotalQtyShipped 
     , AskedPrice, AskedQty, AppvPrice, AppvQty 
    From Tbl_Header a 
    Inner Join Tbl_Detail b On a.RowID = b.RowID 
    Where a.RowID = @RowId 

End --SprocB 

Возможный результат:

PartID  TotalQtyShipped  AskedPrice AskedQty AppvPrice AppQty 
pn1     1000    10   100   10  100 
pn2     550    20   50   15  50 
pn3     2000    5  2000   5  1500 

Пожалуйста, помогите

TL

ответ

1

Если ваше решение основано на динамическом SQL (ServerA.SprocA), вы не можете использовать функции вообще в следующей последовательности вызовов, потому что SQL Server рассматривает функции как детерминированные, и вы не можете изменить состояние SQL Server в вызове функции.

, если бы я на вашем месте, я бы сделал что LnkSrv.DB_History.dbo.SprocA создает денормализованную таблицу (tbl_FnB) со следующими (см ниже) столбцами InstEd возвращения скаляра

CustomerId PartId DateFrom DateTo TotalQtyShipped 

тогда SprocB будет выглядеть следующим образом

Create Procedure SprocB 
    @RowId int 
As 
Begin 

    exec LnkSrv.DB_History.dbo.SprocA; -- creates table Tbl_FnB on its side 

    Select Partid, Tbl.TotalQtyShipped 
     , AskedPrice, AskedQty, AppvPrice, AppvQty 
    From Tbl_Header a 
    Inner Join Tbl_Detail b On a.RowID = b.RowID 
    Inner Join LnkSrv.DB_History.dbo.Tbl_FnB f On f.CustomerId = b.Customerid 
    and f.Partid = b.Partid 
    and f.DateFrom = b.DateFrom 
    and f.DateTo = b.DateTo 
    Where a.RowID = @RowId 

End --SprocB 

Я предположил, что поля CustomerId PartId DateFrom DateTo расположен в Tbl_Detail стол

+0

Если я передам PartId в SprocA, он создаст Tbl_FnB с 1 записью. Если это так, мой SprocB может иметь только 1 запись с TotalQtyShipped. Будет ли также проблема параллелизма, если несколько пользователей запускают SprocB? –

+0

Вам не нужно передавать PartId в SprocA. Вам нужно создать «сырую» таблицу со всеми возможными комбинациями (CustomerId, PartId, DateFrom, DateTo) и соответствующим значением TotalQtyShipped для каждой комбинации. И присоединитесь к этой таблице в конце. –

0

Там нет реальной проблемы с чем вы просите, за исключением того, что вы не можете использовать выполнение внутри функции, как у вас есть;

Однако вы можете сделать это:

create proc [dbo].[GetRowCount] (@TblName NVARCHAR(25) , @Itemid INT,@RowCnt int = 0) 
AS BEGIN 
    DECLARE @Sqlstring nvarchar(2000) 
    set @Sqlstring = 'SELECT @RowCnt = COUNT(*) FROM ['+ @TblName +'] 
    WHERE Itemid = '+ convert(varchar(10),@Itemid) 
    EXEC sp_executesql @Sqlstring,N'@RowCnt int output',@RowCnt output 
END 

...

declare @RowCnt int 
exec [GetRowCount] @TblName='TableName',@Itemid='ItemID',@[email protected] output 
select @RowCnt 

вы должны быть в состоянии приспособить это для вашей собственной ситуации.

+0

Я пробовал этот путь, и он дал мне эту ошибку «Только функции и некоторые расширенные хранимые процедуры могут выполняться из функции» –

Смежные вопросы