如何在单个参数的where子句中传递多个值

时间:2015-10-16 08:58:00

标签: sql sql-server sql-server-2008 tsql stored-procedures

我第一次遇到这种情况。在这里,我必须为单个参数传递多个值,并且参数不必总是具有多个值。有时1有时它会是2或3。所以我怎么把它写在where子句中我很困惑。我已经找了各种来源,但我不知道如何做到这一点。有人建议使用动态查询,但有没有简单的方法来做到这一点。我将发布一个伪代码请告诉我应该怎么做或者最好的方法。

示例代码

IF OBJECT_ID('db.pro_total', 'P') IS NOT NULL
DROP PROCEDURE db.pro_total;
go

create procedure db.pro_total (@value1  int,
                                     @ value2 varchar(50),
                                     @ value3 int,
                                     @ value4 varchar (10),
                                     @ value5 varchar(100)
                                            )
as
begin

select sum(column6) as recived
where status_id=1
and column1 =@ value1
and column2=@value2
and column3=@ value3  
and column4 =@ value4
and column5=@ value5
and time_id between 20150824 and 20150831
group by column1, column2,column3,column4, column5

 end;
  go

与@ value2类似,我希望传递多个值,以便如何传递此值,并且会更改如何调用过程或语法保持不变

调用程序

execute db.pro_tota  '1','119','5400','PA','05L0038663710'

欢迎任何帮助,如果您不理解任何部分,请发表评论。

2 个答案:

答案 0 :(得分:2)

从另一个Stackoverflow答案(https://stackoverflow.com/a/10914602/3007014)复制此内容,但为方便起见,请进行调整。

创建一个函数来分割这样的逗号分隔值(你只需要创建一次) -

    CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX(',', @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(',', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END

然后您可以将其用作

SELECT * FROM dbo.splitstring('1,2,3')

所以对你的情况 -

IF OBJECT_ID('db.pro_total', 'P') IS NOT NULL
DROP PROCEDURE db.pro_total;
go

create procedure db.pro_total (@value1  int,
                                     @ value2 varchar(50),
                                     @ value3 int,
                                     @ value4 varchar (10),
                                     @ value5 varchar(100)
                                            )
as
begin

select sum(column6) as recived
where status_id=1
and column1 =@ value1
and column2 in (select * from dbo.splitstring(@value2))
and column3=@ value3  
and column4 =@ value4
and column5=@ value5
and time_id between 20150824 and 20150831
group by column1, column2,column3,column4, column5

 end;
  go

现在你可以像这样打电话给你 -

execute db.pro_tota  '1','119,223,234','5400','PA','05L0038663710'

请注意,您的第2列定义为varchar(50)。您还没有显示您的表格DDL,因此您希望确保匹配这些DDL,并且仅使用< = 50个字符(包括逗号)调用proc。

我还没有对此进行测试,所以试试吧。我希望你明白这个主意。祝你好运!

答案 1 :(得分:2)

正确的方法是使用Table Valued Parameter

这意味着您使用用户定义的表类型作为输入参数,其中您为多个值使用多行。然后使用标准var updateText = $( "#msgBox button.btn" ).one('click', function() { ... }); $( "#msgBox" ).one('hidden.bs.modal', function() { $( "#msgBox button.btn" ).off('click', updateText); }); 子句过滤结果。

定义表类型:

INNER JOIN

声明此类型的变量,并填充值:

CREATE TYPE Val1Values AS TABLE 
    (val1 INT)

存储过程是:

DECLARE @val1Values AS Val1Values

INSERT INTO @val1Values
  VALUES(1), (3), (4)

因此,我们将表格类型的变量作为输入,使用CREATE PROCEDURE SelectWithValues @TVal1 Val1Values READONLY, @val2 int AS SELECT Table1.* FROM Table1 INNER JOIN @TVal1 tv ON Table1.val1 = tv.val1 WHERE Table1.val2 = @val2 作为过滤器,并使用INNER JOIN作为"简单"像往常一样过滤。

另见[{3}}。