Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie übergebe ich eine Variable, die eine Liste enthält, an eine dynamische SQL-Abfrage?

Einfach

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

Oder was ist der bessere Weg

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;
  • Warum bekomme ich diesen Fehler?

Da Sie wirklich zu viele Parameter übergeben, mehr als nötig, um dies zu verstehen, führen Sie diese Abfrage aus und sehen Sie, was Sie wirklich an Ihre Funktion übergeben

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

was zurückkehrt (und das ist es, was Sie wirklich versuchen auszuführen)

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

statt (was Sie brauchen)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Ok, aber warum sp_executesql ist besser als exec ?

Einfach EXEC zwingt Sie, alle Ihre Variablen zu einer einzigen Zeichenfolge zu verketten, das ist das Schlimmste daran, und das macht Ihren Code vollständig offen für SQL-Injection . Siehe Bad Habits to Kick : Using EXEC() instead of sp_executesql , bedeutet dies nicht, dass sp_executesql ist 100 % sicher, aber es ermöglicht, dass Anweisungen parametrisiert werden während EXEC() nicht, daher ist es sicherer als EXEC in Bezug auf SQL-Injection .

Schließlich, da Sie und Sie die Version nicht angeben, schlage ich vor, dass Sie SPLIT_STRING() Funktion (2016+) eher als Ihre, und wenn Sie keine Version 2016+ haben, dann erstellen Sie Ihre eigene, ohne WHILE zu verwenden Schleife, um eine bessere Leistung zu erzielen, verursachen Sie WHILE Schleife wird langsam ausgeführt, daher sollten Sie es vermeiden.

Beispiele: