sql >> Database >  >> RDS >> Sqlserver

Hoe geef ik een variabele die een lijst bevat door aan een dynamische SQL-query?

Gewoon

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

Of, wat is de betere manier

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;
  • Waarom krijg ik deze foutmelding?

Omdat je echt te veel parameters doorgeeft, meer dan nodig, om dit te begrijpen, voer je deze query uit en kijk je wat je echt doorgeeft aan je functie

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

die zal terugkeren (en dit is wat je echt probeert uit te voeren)

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

in plaats van (wat je nodig hebt)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Ok, maar waarom sp_executesql is beter dan exec ?

Gewoon, EXEC zal je dwingen om al je variabelen samen te voegen tot één enkele string, dat is het ergste, en dat maakt je code volledig open voor SQL-injectie . Zie Bad Habits to Kick : Using EXEC() instead of sp_executesql , betekent dit niet dat sp_executesql is 100% veilig, maar het staat toe dat verklaringen worden geparametriseerd terwijl EXEC() niet, daarom is het veiliger dan EXEC in termen van SQL-injectie .

Tot slot, aangezien u en u de versie niet specificeert, raad ik u aan SPLIT_STRING() functie (2016+) beter dan die van jou, en als je geen 2016+ versie hebt, maak dan je eigen zonder WHILE te gebruiken loop om meer goede prestaties te krijgen, oorzaak WHILE loop zal traag werken, dus je moet het vermijden.

Voorbeelden:



  1. 1432 - Kan geen federatieve tabel maken. De verbindingsreeks van de gegevensbron %s heeft niet de juiste indeling

  2. postgresql postgis Als punt binnen cirkel

  3. Database herstellen in WAMP

  4. jdbc naar MYSQL-fout:geen geschikt stuurprogramma gevonden voor jdbc:mysql://localhost:3306/test?user='root'&password=''