【问题标题】:How to write a stored procedure which contains multiple parameters for in query?如何编写一个包含多个查询参数的存储过程?
【发布时间】:2012-03-17 06:08:18
【问题描述】:

我想写一个这样的存储过程

Create Proc dbo.GetApplicantsByIDs

as

Select * from Applicants where ID in (1,2,3,4)

我如何将 1,2,3 作为参数传递,这些 id 可能是多个。

【问题讨论】:

  • Table-Values 或 String+Split 浮现在脑海中;看了之后发现有很多重复的。大多数情况下,您需要将IN 更改为JOIN
  • 这在功能上与这个问题相同:array parameter in T-SQL - 我建议在那里阅读评分最高的答案。

标签: sql sql-server sql-server-2008 sql-server-2005 tsql


【解决方案1】:

您可以将您的 ID 作为 XML 发送给 SP。

create procedure dbo.GetApplicantsByIDs
  @IDList xml
as

-- Table to hold the id's
declare @IDs table(ID int primary key)

-- Fill table with id's  
insert into @IDs(ID)
select X.ID.value('.', 'int')
from @IDList.nodes('/i') as X(ID)

select * 
from Applicants 
where ID in (select ID 
             from @IDs)

参数字符串应如下所示:

'<i>1</i><i>2</i><i>3</i>'

【讨论】:

    【解决方案2】:

    我认为有更好的解决方案。 您可以创建如下函数:

    CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(8000))
    RETURNS table
    AS
    RETURN (
        WITH Pieces(pn, start, [stop]) AS (
          SELECT 1, 1, CHARINDEX(@sep, @s)
          UNION ALL
          SELECT pn + 1, [stop] + 1, CHARINDEX(@sep, @s, [stop] + 1)
          FROM Pieces
          WHERE [stop] > 0
        )
        SELECT pn as [index],
          SUBSTRING(@s, start, CASE WHEN [stop] > 0 THEN [stop]-start ELSE 8000 END) AS value
        FROM Pieces
      )
    

    然后你可以从输入数据'20,10,15,18,19'得到结果

    SELECT * FROM [dbo].[Split](',', '20,10,15,18,19')
    

    结果将是:

    index   value
    1   20
    2   10
    3   15
    4   18
    5   19
    

    我可以重写你的程序如下:

    Create Proc dbo.GetApplicantsByIDs         
             @Ids NVARCHAR(MAX)
    as         
    
    Select * from Applicants where ID in 
    (SELECT value FROM [dbo].[Split](',', @Ids)
    

    【讨论】:

      【解决方案3】:

      使用表变量的另一种解决方案(为了它):

      if exists (select table_name from information_schema.tables where table_name = 'Applicants')
          drop table Applicants
      go
      
      create table Applicants (
          Id int identity,
          Name varchar(50)
      )
      go
      
      insert Applicants (Name) values ('David')
      insert Applicants (Name) values ('John')
      insert Applicants (Name) values ('Scott')
      insert Applicants (Name) values ('Anna')
      insert Applicants (Name) values ('Esther')
      go
      
      create type IDs as table (
          ID int
      )
      go
      
      if exists (select routine_name from information_schema.routines where routine_name = 'GetApplicantsByIDs')
          drop proc GetApplicantsByIDs
      go
      
      create proc GetApplicantsByIDs (
          @IDs IDs readonly
      )
      as 
      begin
          select * from Applicants A where Id in (select * from @IDs)
      end
      go
      
      
      declare @MyIDs as IDs
      insert @MyIDs values (2)
      insert @MyIDs values (4)
      insert @MyIDs values (1)
      
      exec GetApplicantsByIDs @MyIDs
      go
      

      产生: 1 大卫 2约翰 4 安娜

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-15
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 1970-01-01
        • 2011-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多