0

私がインターネット上で見つけたほとんどの状況とは異なり、人々が c# のようなアプリケーションから sproc に ID のリストを渡す必要がある場合は、ID を分割して 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 SELECT *

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

WHERE 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 
    

    WHERE 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 に答える