0

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

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

我需要向函数添加一个约束,以便它不会构建所有 Horizo​​ntals 的结果集。

--这是共享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 [Storefront].[proc_GetBayHorizo​​ntals] @BayID INT AS BEGIN SET NOCOUNT ON;

        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)

提前谢谢你!

4

1 回答 1

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
于 2012-07-17T00:42:25.033 回答