Puede haber un procedimiento almacenado parámetros dinámicos que se utiliza en una cláusula de “IN”?
-
13-09-2019 - |
Pregunta
Quiero ejecutar una consulta como la siguiente:
SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)
pero la cantidad de Id 's pasa a la cláusula IN se determina sólo en tiempo de ejecución.
¿Tengo que utilizar SQL dinámico o se puede hacer esto con un procedimiento almacenado?
ACTUALIZACIÓN: Si cualquiera de estas opciones está disponible, ¿cuál es mejor?
Gracias.
Solución
En función de la versión de SQL Server, puede hacer esto de dos maneras diferentes.
Para SQL 2000/2005, se puede utilizar un parámetro (tipo varchar) que tiene una lista delimitada de documentos de identidad. Crear una UDF que analizar el varchar y devolver una tabla que contiene los elementos. A continuación, hacer su cláusula IN ir en contra de la tabla (es decir, ... IN (SELECT ID DE @ReturnTable)).
Este es un ejemplo de lo que el contenido de la UDF se vería así: http://pietschsoft.com/post /2006/02/03/T-SQL-Parse-a-delimited-string.aspx
Para SQL 2008, puede hacer lo mismo; Sin embargo, en lugar de pasar un parámetro VARCHAR sólo puede ir al grano y pasar en un parámetro de la tabla. La cláusula IN aún tendría una subconsulta pero funcionaría todo lo mismo. Por otra parte, una vez que tenga la tabla que acaba puede hacer una combinación interna en él y eludir la necesidad de la cláusula IN.
EDIT:. UDF agregado para analizar una cadena delimitada enlace
Otros consejos
Solución describe a continuación:
Las matrices y listas de SQL Server 2005
Un texto SQL por Erland Sommarskog, SQL Server MVP
Puede hacer absolutamente esto en un procedimiento almacenado.
crear una tabla temporal dentro del procedimiento almacenado e insertar los valores divididos sobre las comas o cualquier delimitador entonces hacen esto
SELECT * FROM Studio WHERE Id IN (select id from temptable)
A continuación, elimine la tabla.
Aquí es una UDF que he estado usando desde MSSQL 2000. He encontrado esto en alguna parte -. Lo siento, no recuerdo donde
Básicamente, se puede hacer una combinación en la UDF, en el que el primer parámetro es la cadena delimitada, y el segundo parámetro es el delimitador.
t1.somecolumn SELECT FROM t1 sometable INNER JOIN dbo.Split (@delimitedVar, '') t2 EN 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
En SQL 2008 se puede utilizar un valorada parámetro .
En SQL 2005, usted debe utilizar SQL dinámico a menos que quiera pasar a la lista como XML y utilizar el procesamiento de XML en el procedimiento para triturar el XML de nuevo en una variable de tabla.
declarar una mesa @Temp y dividir los valores en ella. entonces usted podría hacer
SELECT * FROM Estudio s combinación interna tb @temptable en s.ID = tb.ID