2015-10-16 37 views
0

我第一次遇到这种情况。在这里,我必须为单个参数传递多个值,并且参数不一定总是有多个值。有时候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 [email protected] value1 
and [email protected] 
and [email protected] value3 
and column4 [email protected] value4 
and [email protected] 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' 

欢迎任何帮助,如果你不明白任何部分只是评论。

+0

您可以使用@ value2的逗号分隔值,然后使用IN子句而不是= –

+0

@RahulTripathi“IN”将如何工作?它仍然会看到一个单一的值。 – DavidG

+0

1)使用函数将'''值分开2)你可以使用XML路径 – wiretext

回答

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)[email protected]) 
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 [email protected] value1 
and column2 in (select * from dbo.splitstring(@value2)) 
and [email protected] value3 
and column4 [email protected] value4 
and [email protected] value5 
and time_id between 20150824 and 20150831 
group by column1, column2,column3,column4, column5 

end; 
    go 

现在你可以这样称呼你的proc了 -

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

请注意,您的列2被定义为varchar(50)。你没有显示你的表DDL,所以你想确保你匹配这些,也只能调用与< = 50个字符,包括逗号的过程。

我还没有测试过,所以试试看。我希望你明白这个主意。祝你好运!

+0

谢谢,但我有另一个问题,请你看看 –

2

正确的做法是使用Table Valued Parameter

这意味着您使用用户定义的表格类型作为输入参数,其中您将多行用于多个值。然后,您使用标准的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作为过滤器,并使用照常使用“简单”过滤器的。

另请参阅此活在SQLFiddle上。

+0

太棒了!但我已经完成了,你能帮我编辑的部分 –