【问题标题】:calling a remote sproc from a function从函数调用远程存储过程
【发布时间】:2013-07-12 02:15:36
【问题描述】:

我有一个存储过程 SprocA 驻留在 ServerA 上。 SprocA 接受 4 个参数,执行一个动态 sql 并返回一个包含 1 列(1 个整数值)的记录。 我希望能够从 ServerB 上的函数 FnB 调用它,以便我可以在服务器 ServerB 上的存储过程 SprocB 中使用它来返回记录集。

例如,我想要这样的东西

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

【问题讨论】:

    标签: sql sql-server openquery sp-executesql


    【解决方案1】:

    如果您的解决方案基于动态 SQL (ServerA.SprocA),则您根本无法在以下调用序列中使用函数,因为 SQL Server 将函数视为确定性,您无法在函数调用中更改 SQL Server 状态。

    如果我在你的位置,我会让 LnkSrv.DB_History.dbo.SprocA 创建非规范化表 (tbl_FnB),其中包含以下(见下文)列返回标量值

    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 表中

    【讨论】:

    • 如果我将 PartId 传递给 SprocA,它会创建带有 1 条记录的 Tbl_FnB。如果是这样,我的 SprocB 可能只有 1 条 TotalQtyShipped 记录。如果多个用户运行 SprocB 是否也会出现并发问题?
    • 您不需要将 PartId 传递给 SprocA。您需要生成“原始”表,其中包含 (CustomerId、PartId、DateFrom、DateTo) 的所有可能组合以及每个组合的相应 TotalQtyShipped 值。并在最后加入这个表。
    【解决方案2】:

    除了你不能在函数中使用 execute 之外,你所要求的没有真正的问题;

    但是你可以这样做:

    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',@RowCnt=@RowCnt output
    select @RowCnt
    

    您应该能够根据自己的情况进行调整。

    【讨论】:

    • 我试过这种方式,它给了我这个错误“只有函数和一些扩展存储过程可以在函数内执行”
    猜你喜欢
    • 1970-01-01
    • 2020-01-09
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 2014-10-09
    • 1970-01-01
    • 2013-06-06
    相关资源
    最近更新 更多