Può una stored procedure sono parametri dinamici per essere utilizzato in un “IN” clausola?
-
13-09-2019 - |
Domanda
Vorrei eseguire una query come questa:
SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)
ma la quantità di Id's passato IN la clausola è determinato solo in fase di runtime.
Devo usare SQL dinamico o questo può essere fatto con una stored procedure?
AGGIORNAMENTO: Se l'opzione è disponibile, qual è il migliore?
Grazie.
Soluzione
A seconda della versione di Sql Server, è possibile fare questo in uno di due modi diversi.
Per Sql 2000/2005, è possibile utilizzare un parametro (tipo varchar) che ha delimitato elenco di Id.Creare un UDF che sarebbero parse varchar e restituire una tabella che contiene gli elementi.Quindi, la clausola di andare contro il tavolo (cioè...IN (Select ID FROM @ReturnTable)).
Ecco un esempio di ciò che il contenuto del FSU sarebbe simile:http://pietschsoft.com/post/2006/02/03/T-SQL-Parse-a-delimited-string.aspx
Per Sql server 2008, è possibile fare la stessa cosa;tuttavia, invece di passare in un varchar parametro si può solo tagliare la testa al toro e passare un parametro di Tabella.La clausola avrebbe ancora una sottoquery ma dovrebbe funzionare lo stesso.In alternativa, una volta che avete il tavolo si può solo fare una Inner Join su di esso e può eludere la necessità per la clausola.
EDIT:aggiunto UDF per il parsing di una stringa delimitata link.
Altri suggerimenti
soluzione descritta qui:
array e liste in SQL Server 2005
Un testo SQL da Erland Sommarskog, SQL Server MVP
Si può assolutamente fare questo in una stored procedure.
creare una tabella temporanea all'interno della stored procedure e inserire i valori divisi sulle virgole o qualsiasi delimitatore poi fare questo
SELECT * FROM Studio WHERE Id IN (select id from temptable)
Quindi eliminare la tabella.
Ecco un UDF che ho usato da quando MSSQL 2000. Ho trovato questo da qualche parte -. Mi dispiace, non ricordo dove
In sostanza, si può fare un join sul UDF, dove il primo parametro è la stringa delimitata, e il secondo parametro è il delimitatore.
Seleziona t1.somecolumn da T1 SomeTable 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 è possibile utilizzare un valore dei parametri .
In SQL 2005, è necessario utilizzare SQL dinamico a meno che non si desidera passare alla lista come XML e utilizzare elaborazione XML nella procedura di distruggere il codice XML di nuovo in una variabile di tabella.
dichiarare una tabella @temp e dividere i valori in esso. allora si potrebbe fare
select * from Studio s inner join tb @temptable su s.ID = tb.ID