【问题标题】:SQL Server How to pass a list of ids from sproc to functionSQL Server如何将id列表从sproc传递给函数
【发布时间】:2012-07-17 13:58:00
【问题描述】:

与我在互联网上发现的大多数情况不同,当人们需要将 id 列表从 c# 之类的应用程序传递给 sproc 然后拆分 id 以便它们可以在 WHERE 子句中使用时,例如 WHERE IN (4 ,5,6,7,7,8)

我需要从传递 id 列表的 sql 存储过程调用 sql 函数。我需要知道最好的方法,如果可能的话最好不要引入 .Split 函数。

我需要为函数添加一个约束,这样它就不会构建所有水平的结果集。

--这是共享sql函数

ALTER FUNCTION [Storefront].[ufn_GetHorizontals] 
(
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT myColumList.* 'omitted'

FROM   Storefront.Horizontal h          with(nolock)                           JOIN
        Catelog.Part pt                 with(nolock)ON h.PartID = pt.ID        JOIN
        Catelog.Brand bd                with(nolock)ON pt.BrandID = bd.ID      JOIN
        Storefront.Size sz              with(nolock)ON sz.ID = h.SizeID        JOIN
        Storefront.Daylite dl           with(nolock)ON sz.ID = dl.SizeID       JOIN
        Storefront.Siteline sl          with(nolock)ON sl.ID = h.SitelineID    JOIN
        Storefront.Finish f             with(nolock)ON f.ID = h.FinishID      LEFT JOIN
        Storefront.HorizontalGlass hg   with(nolock)ON hg.HorizontalID = h.ID LEFT JOIN
        Catelog.Glass g                 with(nolock)ON hg.GlassID = g.ID
)

--这里有几个例子说明了我不想处理这个问题的方式,因为这显然是错误的。

-示例 1 选择 *

FROM Storefront.Leaf l with(nolock) JOIN Storefront.LeafHorizo​​ntal lh with(nolock)ON l.ID = lh.LeafID JOIN Storefront.ufn_GetHorizo​​ntals() h ON lh.Horizo​​ntalID = h.ID

哪里 l.ID = @LeafID;

  • 示例 2

    ALTER proc [店面].[proc_GetBayHorizo​​ntals] @BayID INT 作为 开始 设置无计数;

        SELECT  *
    
        FROM   Storefront.Bay b           with(nolock)           JOIN
                Storefront.BayHorizontal bh   with(nolock)ON b.ID = bh.BayID JOIN
                Storefront.ufn_GetHorizontals() h ON bh.HorizontalID = h.ID 
    

    在哪里 b.ID = @BayID;


我需要一些类似的东西。

    ALTER FUNCTION [Storefront].[ufn_GetHorizontals] 
    (
      @MyListOfIdsFromTheStoredProcedure SOMEDATATYPE;
    )
    RETURNS TABLE 
    AS
    RETURN 
    (
        SELECT myColumList.* 'omitted'

    FROM   Storefront.Horizontal h          with(nolock)                           JOIN
            Catelog.Part pt                 with(nolock)ON h.PartID = pt.ID        JOIN
            Catelog.Brand bd                with(nolock)ON pt.BrandID = bd.ID      JOIN
            Storefront.Size sz              with(nolock)ON sz.ID = h.SizeID        JOIN
            Storefront.Daylite dl           with(nolock)ON sz.ID = dl.SizeID       JOIN
            Storefront.Siteline sl          with(nolock)ON sl.ID = h.SitelineID    JOIN
            Storefront.Finish f             with(nolock)ON f.ID = h.FinishID      LEFT JOIN
            Storefront.HorizontalGlass hg   with(nolock)ON hg.HorizontalID = h.ID LEFT JOIN
            Catelog.Glass g                 with(nolock)ON hg.GlassID = g.ID


  **********--->  WHERE h.ID IN(@MyListOfIdsFromTheStoredProcedure )

  )

***-->存储过程改成这样。

    SELECT  *
              FROM
       Storefront.ufn_GetHorizontals(SELECT HorizontalID FROM Storefront.BayHorizontal bh
                                         WHERE bh.BayID = @BayID)

提前谢谢你!

【问题讨论】:

    标签: sql database stored-procedures sql-function


    【解决方案1】:

    内联函数GetBayIDs() 采用单个整数并创建ID 的XML 文档,该文档被传递到您的函数中,随后传递给Split() 函数以过滤函数中的数据集。没有Storefront.BayHorizontal 很难测试,但我认为这非常接近......

    create function dbo.GetBayIDs(@BayID int) returns xml
    as
    begin
      declare @xml varchar(max), @i int
    
      set @xml = '<root>'
    
      declare cr cursor local for
        SELECT HorizontalID
        FROM   Storefront.BayHorizontal bh
        WHERE  bh.BayID = @BayID
    
      open cr
      fetch next from cr into @i
    
      while @@fetch_status = 0
      begin
        set @xml = @xml + '<r>' + cast(@i as varchar(10)) + '</r>'
        fetch next from cr into @i
      end
    
      close cr
      deallocate cr
    
      set @xml = @xml + '</root>'
    
      return @xml
    end
    go
    
    create function dbo.Split(@ids xml) returns @rtn table (id varchar(10))
    as
    begin
      insert into @rtn
      select r.value('.', 'varchar(10)') as [id]
      from @ids.nodes('//root/r') as records(r)
    
      return
    end
    go
    
    ALTER FUNCTION [Storefront].[ufn_GetHorizontals] 
        (
          @idlist xml
        )
        RETURNS TABLE 
        AS
        RETURN 
        (
            SELECT myColumList.* 'omitted'
        FROM   Storefront.Horizontal h          with(nolock)                           JOIN
                Catelog.Part pt                 with(nolock)ON h.PartID = pt.ID        JOIN
                Catelog.Brand bd                with(nolock)ON pt.BrandID = bd.ID      JOIN
                Storefront.Size sz              with(nolock)ON sz.ID = h.SizeID        JOIN
                Storefront.Daylite dl           with(nolock)ON sz.ID = dl.SizeID       JOIN
                Storefront.Siteline sl          with(nolock)ON sl.ID = h.SitelineID    JOIN
                Storefront.Finish f             with(nolock)ON f.ID = h.FinishID      LEFT JOIN
                Storefront.HorizontalGlass hg   with(nolock)ON hg.HorizontalID = h.ID LEFT JOIN
                Catelog.Glass g                 with(nolock)ON hg.GlassID = g.ID      LEFT JOIN
                dbo.Split(@idlist) spl                      ON h.id = spl.id
      )
    go
    
    declare @BayID int = 123
    
    SELECT *
    FROM   Storefront.ufn_GetHorizontals(dbo.GetBayIDs(@BayID))
    
    go
    drop function dbo.Split
    go
    drop function dbo.GetIDs
    

    【讨论】:

    • 我想这意味着我将不得不使用某种类型的带有 XML 的 split() 方法的字符串?
    • 我确信有一些方法可以在不使用 XML 的情况下做到这一点,但这无疑是一种简单的方法。我会看看我是否可以把它变成一个内联函数......
    • 如果我可以像这样将 id 从 sproc 传递给函数,那就太棒了。 SELECT * FROM Storefront.ufn_GetHorizo​​ntals(SELECT Horizo​​ntalID FROM Storefront.BayHorizo​​ntal bh WHERE bh.BayID = @BayID)
    • ID 不是已经是逗号分隔的值列表了吗?您是否还尝试使用 GetHorizo​​ntals() 函数构建整数列表?
    • @MyListOfIdsFromTheStoredProcedure不是逗号分隔的id列表吗?或者,当它仔细观察您要执行的操作时,您似乎希望将单个字段数据集传递给可以在函数内链接的函数,以限制函数返回的行。对吗?
    猜你喜欢
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多