2009-06-10 62 views
6

我想运行这样的查询:存储过程是否可以在“IN”子句中使用动态参数?

SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566) 

,但传递给IN子句标识的是仅在运行时确定的金额。

我必须使用动态SQL,还是可以使用存储过程完成这项工作?

更新: 如果任一选项可用,哪一个更好?

谢谢。

+0

是由用户输入生成的ID的? – Eric 2009-06-10 17:35:13

+0

用户使用复选框选择要搜索的记录,但他们无法控制实际“Id”的含义。 – orandov 2009-06-10 17:39:06

+0

然后,动态SQL不是一个坏主意,如果它不受注射......但尝试我贴出来的答案是安全的。 – Eric 2009-06-10 17:41:07

回答

8

根据您的SQL Server版本,你可以通过两种不同的方式做到这一点。

对于Sql 2000/2005,可以使用具有分隔ID列表的参数(类型varchar)。创建一个将解析varchar并返回包含项目的表的UDF。然后让你的IN子句对着表(即... IN(从@返回表中选择ID))。

这里的UDF的内容是什么样子的例子: http://pietschsoft.com/post/2006/02/03/T-SQL-Parse-a-delimited-string.aspx

对于SQL 2008,你可以做同样的事情;然而不是传递一个varchar参数,你可以切换到chase并传入一个Table参数。 IN子句仍然有一个子查询,但它的工作原理完全相同。另外,一旦你有了表格,你可以在它上面做一个Inner Join,并绕过IN子句的需要。

编辑:添加UDF解析分隔字符串链接。

0

在SQL 2008中,您可以使用table valued parameter

在SQL 2005中,您必须使用动态SQL,除非您想将该列表作为XML传递,并在过程中使用XML处理将XML分解为表变量。

0

声明一个@temp表并将值分解。那么你可以做

SELECT * FROM工作室内心上s.ID加入 @temptable TB = tb.ID

3

您绝对可以做到这一点的存储过程。

创建存储过程中临时表并插入值拆分的逗号或任何分隔符,然后做这个

SELECT * FROM Studio WHERE Id IN (select id from temptable) 

然后删除该表。

1

这是自MSSQL 2000以来我一直在使用的UDF。我发现这个地方 - 抱歉,不记得在哪里。

基本上,您可以在UDF上进行连接,其中第一个参数是分隔字符串,第二个参数是分隔符。

SELECT t1.somecolumn FROM sometable T1 INNER JOIN dbo.Split(@delimitedVar, '')T2 ON t1.ID = t2.Element

CREATE FUNCTION [dbo].[Split] 
(
@vcDelimitedString varchar(max), 
@vcDelimiter varchar(100) 
) 
RETURNS @tblArray TABLE 
    (
    ElementID smallint IDENTITY(1,1), --Array index 
    Element varchar(1000) --Array element contents 
    ) 
AS 
BEGIN 
    DECLARE @siIndex smallint, @siStart smallint, @siDelSize smallint 
    SET @siDelSize = LEN(@vcDelimiter) 
    --loop through source string and add elements to destination table array 
    WHILE LEN(@vcDelimitedString) > 0 
    BEGIN 
     SET @siIndex = CHARINDEX(@vcDelimiter, @vcDelimitedString) 
     IF @siIndex = 0 
     BEGIN 
      INSERT INTO @tblArray VALUES(@vcDelimitedString) 
      BREAK 
     END 
     ELSE 
     BEGIN 
      INSERT INTO @tblArray VALUES(SUBSTRING(@vcDelimitedString, 1,@siIndex - 1)) 
      SET @siStart = @siIndex + @siDelSize 
      SET @vcDelimitedString = SUBSTRING(@vcDelimitedString, @siStart , LEN(@vcDelimitedString) - @siStart + 1) 
     END 
    END 
    RETURN 
END 
相关问题