sql >> Database teknologi >  >> RDS >> Sqlserver

Hvordan sender jeg en variabel, der indeholder en liste, til en dynamisk SQL-forespørgsel?

Simpelthen

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

Eller, hvilket er den bedste måde

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;
  • Hvorfor får jeg denne fejl?

Fordi du virkelig sender for mange parametre, mere end det er nødvendigt, for at forstå dette, kør denne forespørgsel og se, hvad du egentlig er, videregive til din funktion

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

som vil vende tilbage (og det er det, du virkelig prøver at udføre)

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

i stedet for (hvilket er hvad du har brug for)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Ok, men hvorfor sp_executesql er bedre end exec ?

Simpelthen EXEC vil tvinge dig til at sammenkæde alle dine variable i én enkelt streng, det er det værste ved det, og det gør din kode helt åben for SQL-injektion . Se Dårlige vaner at sparke:Brug af EXEC() i stedet for sp_executesql , betyder det ikke, at sp_executesql er 100 % sikker, men det giver mulighed for at parameterisere udsagn mens EXEC() gør det ikke, derfor er det mere sikkert end EXEC med hensyn til SQL-injektion .

Endelig, siden du tagger og du ikke angiver versionen, foreslår jeg, at du bruger SPLIT_STRING() funktion (2016+) rathar end din, og hvis du ikke har 2016+ version, så lav din egen uden at bruge WHILE loop for at opnå mere god ydeevne, forårsage WHILE loop vil fungere langsomt, så du bør undgå det.

Eksempler:



  1. Anbefal venligst den bedste massesletningsmulighed

  2. mysql tæller rækker med loop

  3. Noget hurtigere end get_headers()

  4. Konverter Oracle CLOB-data til streng i c#