6

我想运行这样的查询:

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

但传递给 IN 子句的Id数量仅在运行时确定。

我必须使用动态 SQL 还是可以使用存储过程来完成?

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

谢谢。

4

6 回答 6

8

根据您的 Sql Server 版本,您可以使用两种不同的方法之一来执行此操作。

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

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

对于 Sql 2008,你可以做同样的事情;但是,您可以直接切入正题并传入 Table 参数,而不是传入 varchar 参数。IN 子句仍然有一个子查询,但它的工作原理都是一样的。或者,一旦你有了表,你就可以在它上面做一个 Inner Join 并规避对 IN 子句的需要。

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

于 2009-06-10T17:29:28.627 回答
5

此处描述的解决方案:

SQL Server 2005 中的数组和列表

由 SQL Server MVP Erland Sommarskog 编写的 SQL 文本

http://www.sommarskog.se/arrays-in-sql-2005.html

于 2009-06-10T17:28:19.533 回答
3

您绝对可以在存储过程中执行此操作。

在存储过程中创建一个临时表并插入以逗号或任何分隔符拆分的值然后执行此操作

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

然后删除表。

于 2009-06-10T17:37:18.813 回答
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
于 2009-06-10T17:39:40.667 回答
0

在 SQL 2008 中,您可以使用表值参数

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

于 2009-06-10T17:29:54.460 回答
0

声明一个 @temp 表并将值拆分到其中。那么你可以做

select * from Studio s inner join @temptable tb on s.ID=tb.ID

于 2009-06-10T17:31:00.277 回答