代码之家  ›  专栏  ›  技术社区  ›  orandov

存储过程是否可以在“in”子句中使用动态参数?

  •  6
  • orandov  · 技术社区  · 16 年前

    我想运行这样的查询:

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

    但是 身份证件 只在运行时确定传递给IN子句的。

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

    更新: 如果有两种选择,哪一种更好?

    谢谢。

    6 回复  |  直到 16 年前
        1
  •  8
  •   JamesEggers    16 年前

    根据您的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,您可以做同样的事情;但是,您可以直接切换到chase并传入表参数,而不是传入varchar参数。IN子句仍然有一个子查询,但它的工作原理是一样的。或者,一旦您有了表,就可以对其进行内部联接,从而避免了对in子句的需要。

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

        2
  •  5
  •   A-K    16 年前

    这里描述的解决方案:

    SQL Server 2005中的数组和列表

    Erland Sommarskog、SQL Server MVP提供的SQL文本

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

        3
  •  3
  •   Eric    16 年前

    您完全可以在存储过程中执行此操作。

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

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

    然后删除表。

        4
  •  1
  •   ScottE    16 年前

    这是我从2000年开始使用的一个UDF。我在某个地方找到了这个-对不起,不记得在哪里。

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

    从T1.ID=t2.element上的someTable T1 inner join dbo.split(@delimitedvar,,')t2中选择T1.someColumn。

    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
    
        5
  •  0
  •   Remus Rusanu    16 年前

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

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

        6
  •  0
  •   Christopher Klein    16 年前

    声明一个@temp表并将值拆分为它。那你就可以了

    从Studio的内部联接中选择*。 “暴发性结核病” 关于S.ID= T.B.ID

    推荐文章