存储过程可以在“ IN”子句中使用动态参数?
-
13-09-2019 - |
题
我想运行这样的查询:
SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)
但是数量 ID仅在运行时确定输入子句。
我必须使用动态SQL还是可以使用存储过程来完成?
更新:如果两个选项可用,哪个更好?
谢谢。
解决方案
根据您的SQL Server版本,您可以执行两种不同的方式之一。
对于SQL 2000/2005,您可以使用具有IDS界定列表的参数(type varchar)。创建一个可以解析varchar并返回包含项目的表的UDF。然后使您的子句符合表(即...从@returntable中选择ID))。
这是UDF内容的示例:http://pietschsoft.com/post/2006/02/03/t-sql-parse-a-delimited-string.aspx
对于SQL 2008,您可以做同样的事情;但是,您可以将Chase切入Chase并传递到表参数,而不是传递Varchar参数。该子句仍然有一个子查询,但它的作用也一样。另外,一旦有了表,就可以在其上进行内部连接,并规避对in子句的需求。
编辑:添加了用于解析界定字符串链接的UDF。
其他提示
这里描述的解决方案:
SQL Server 2005中的数组和列表
SQL Sommarskog的SQL文本,SQL Server MVP
您绝对可以在存储过程中执行此操作。
在存储过程中创建一个临时表,然后插入逗号或任何定界符上的值分开的值,然后执行此操作
SELECT * FROM Studio WHERE Id IN (select id from temptable)
然后删除表。
这是自MSSQL 2000以来一直使用的UDF。我在某个地方发现了这一点 - 对不起,不记得在哪里。
基本上,您可以在UDF上进行连接,其中第一个参数是划界字符串,第二个参数是定界符。
从某种程度上从t1 t1 in niner join dbo.split(@delimitedvar,',')中选择t1。
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
在SQL 2008中,您可以使用 表值参数.
在SQL 2005中,您必须使用动态SQL,除非要将列表作为XML传递,并在过程中使用XML处理将XML切成XML返回表变量。
声明一个@Temp表并将值拆分为其中。那你可以做
从Studio的内部加入@Temptble TB上的S.id = tb.id选择 * *