我想运行这样的查询:存储过程是否可以在“IN”子句中使用动态参数?
SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)
,但传递给IN子句标识的是仅在运行时确定的金额。
我必须使用动态SQL,还是可以使用存储过程完成这项工作?
更新: 如果任一选项可用,哪一个更好?
谢谢。
我想运行这样的查询:存储过程是否可以在“IN”子句中使用动态参数?
SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)
,但传递给IN子句标识的是仅在运行时确定的金额。
我必须使用动态SQL,还是可以使用存储过程完成这项工作?
更新: 如果任一选项可用,哪一个更好?
谢谢。
根据您的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解析分隔字符串链接。
解决方案说明如下:
数组和列表在SQL Server 2005中
通过厄兰Sommarskog的SQL文本,SQL服务器MVP
在SQL 2008中,您可以使用table valued parameter。
在SQL 2005中,您必须使用动态SQL,除非您想将该列表作为XML传递,并在过程中使用XML处理将XML分解为表变量。
声明一个@temp表并将值分解。那么你可以做
SELECT * FROM工作室内心上s.ID加入 @temptable TB = tb.ID
您绝对可以做到这一点的存储过程。
创建存储过程中临时表并插入值拆分的逗号或任何分隔符,然后做这个
SELECT * FROM Studio WHERE Id IN (select id from temptable)
然后删除该表。
这是自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
是由用户输入生成的ID的? – Eric 2009-06-10 17:35:13
用户使用复选框选择要搜索的记录,但他们无法控制实际“Id”的含义。 – orandov 2009-06-10 17:39:06
然后,动态SQL不是一个坏主意,如果它不受注射......但尝试我贴出来的答案是安全的。 – Eric 2009-06-10 17:41:07