sql >> Databáze >  >> RDS >> Sqlserver

Jak předám proměnnou obsahující seznam do dynamického dotazu SQL?

Jednoduše

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

Nebo, který je lepší způsob

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;
  • Proč se mi zobrazuje tato chyba?

Protože opravdu předáváte příliš mnoho parametrů, více než je potřeba, abyste pochopili tento dotaz, spusťte tento dotaz a viděli, co skutečně předáváte své funkci

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

který se vrátí (a to se skutečně snažíte provést)

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

místo (což je to, co potřebujete)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Dobře, ale proč sp_executesql je lepší než exec ?

Jednoduše EXEC vás donutí zřetězit všechny vaše proměnné do jednoho jediného řetězce, to je na tom nejhorší a váš kód je plně otevřený vkládání SQL . Viz Bad Habits to Kick : Using EXEC() instead of sp_executesql , to neznamená, že sp_executesql je 100% bezpečný, ale umožňuje příkazy parametrizovat zatímco EXEC() není, proto je bezpečnější než EXEC z hlediska SQL injection .

Konečně, protože označíte a neuvedete verzi, doporučuji použít SPLIT_STRING() funkce (2016+) je spíše než ta vaše, a pokud nemáte verzi 2016+, vytvořte si vlastní bez použití WHILE smyčka pro získání lepšího výkonu, způsobí WHILE smyčka bude fungovat pomalu, proto byste se jí měli vyhnout.

Příklady:



  1. Jak vrátit zlomkové sekundy z hodnoty Datetime v Oracle

  2. Chyba aktualizace Liquibase

  3. Ořízněte mezery (nový řádek a místo tabulátoru) v řetězci v Oracle

  4. sql primární klíč a index