sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo paso una variable que contiene una lista a una consulta SQL dinámica?

Simplemente

EXECUTE ('select id from  [dbo].[CSVToTable] ('''[email protected]+''')')
        declare @listOfIDs varchar(1000);

O, cuál es la mejor manera

SET @listOfIDs = '5, 6, 7, 8, 9, 15, 28, 31, 49, 51, 59, 61'; 

EXECUTE sp_executesql N'select id from  [dbo].[CSVToTable] (@listOfIDs)',
                      N'@listOfIDs VARCHAR(1000)',
                      @listOfIDs;
  • ¿Por qué aparece este error?

Debido a que realmente pasa demasiados parámetros, más de los necesarios, para comprender esto, ejecute esta consulta y vea lo que realmente está pasando a su función

SELECT 'select id from  [dbo].[CSVToTable] ('[email protected]+')';

que regresará (y esto es lo que realmente intentas ejecutar)

select id from  [dbo].[CSVToTable] (5, 6, 7, 8, 9, 15, 28, 31, 49, 51, 59, 61)

en lugar de (que es lo que necesitas)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Vale, pero ¿por qué sp_executesql? es mejor que exec ?

Simplemente, EXEC lo obligará a concatenar todas sus variables en una sola cadena, eso es lo peor de todo, y eso hace que su código esté completamente abierto a inyección SQL . Consulte Bad Habits to Kick : Using EXEC() instead of sp_executesql , esto no significa que sp_executesql es 100% seguro, pero permite parametrizar las sentencias mientras EXEC() no, por lo tanto, es más seguro que EXEC en términos de inyección SQL .

Finalmente, dado que etiqueta y no especifica la versión, le sugiero que use SPLIT_STRING() función (2016+) más que la suya, y si no tiene la versión 2016+, cree la suya propia sin usar WHILE bucle para obtener un mejor rendimiento, causa WHILE el bucle funcionará lento, por lo que debe evitarlo.

Ejemplos: