ストアドプロシージャには、「in」節で使用する動的なパラメーターを持つことができますか?

StackOverflow https://stackoverflow.com/questions/977021

質問

このようなクエリを実行したい:

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

しかし、の量 IDIN句に渡されたのは、実行時にのみ決定されます。

動的なSQLを使用する必要がありますか、それともストアドプロシージャでこれを実行できますか?

アップデート:いずれかのオプションが利用可能な場合、どれが優れていますか?

ありがとう。

役に立ちましたか?

解決

SQL Serverのバージョンによっては、2つの異なる方法のいずれかを実行できます。

SQL 2000/2005の場合、IDの区切りリストを持つパラメーター(タイプVarchar)を使用できます。 Varcharを解析し、アイテムを含むテーブルを返すUDFを作成します。次に、句にテーブルに逆らうようにします(つまり... in(@returntableからidを選択))。

UDFの内容がどのように見えるかの例は次のとおりです。http://pietschsoft.com/post/2006/02/03/t-sql-parse-a-delimited-string.aspx

SQL 2008では、同じことができます。ただし、Varcharパラメーターを渡す代わりに、Chaseにカットしてテーブルパラメーターを渡すことができます。 In句にはまだサブクエリがありますが、すべて同じように機能します。または、テーブルができたら、内側の結合を実行して、IN句の必要性を回避できます。

編集:区切り文字列リンクを解析するためにUDFを追加しました。

他のヒント

Solution described here:

Arrays and Lists in SQL Server 2005

An SQL text by Erland Sommarskog, SQL Server MVP

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

You can absolutely do this in a stored procedure.

create a temp table inside the stored procedure and insert the values split on the commas or any delimiter then do this

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

Then delete the table.

Here is a UDF that I've been using since MSSQL 2000. I found this somewhere - sorry, can't remember where.

Basically, you can do a join on the UDF, where the first param is the delimited string, and the second param is the delimiter.

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

In SQL 2008 you can use a table valued parameter.

In SQL 2005 you must use dynamic SQL unless you want to pass the list as XML and use XML processing in the procedure to shred the XML back into a table variable.

declare a @temp table and split the values into it. then you could do

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top