ストアドプロシージャには、「in」節で使用する動的なパラメーターを持つことができますか?
-
13-09-2019 - |
質問
このようなクエリを実行したい:
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
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