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

sp_executesql s příkazem 'IN'

Důvod, proč to nefunguje, je ten, že @P1 je považováno za jednu, jedinou hodnotu.

např. když je @Code X101,B202, pak se dotaz právě spouští jako:SELECT * FROM Table WHERE RegionCode IN ('X101,B202') Takže hledá RegionCode s hodnotou, která je obsažena v @P1. I když zahrnete jednoduché uvozovky, znamená to, že hodnota, kterou hledá v RegionCode, bude obsahovat tyto jednoduché uvozovky.

Ve skutečnosti byste museli zřetězit proměnnou @Code do textu příkazu @Cmd sql, aby fungovala tak, jak si myslíte:

SET @Code = '''X101'',''B202'''
SET @Cmd = 'SELECT * FROM Table WHERE RegionCode IN (' + @Code + ')'
EXECUTE (@Cmd)

Je zřejmé, že se tím jen otevíráte SQL injection, takže byste měli být velmi opatrní, pokud jste zvolili tento přístup, abyste se ujistili, že se tomu budete bránit.

Existují alternativní způsoby řešení této situace, kdy chcete předat dynamický seznam hodnot, které chcete hledat.

Podívejte se na příklady na mém blogu pro 2 přístupy, které byste mohli použít s SQL Server 2005. Jedním z nich je předání CSV seznamu ve tvaru „Hodnota1,Hodnota2,Hodnota3“, který pak rozdělíte do proměnné TABLE pomocí uživatelsky definované funkce (je o tom spousta zmínek přístup, pokud provedete rychlé googlování nebo vyhledávání na tomto webu). Po rozdělení připojíte tuto proměnnou TABLE k hlavnímu dotazu. Druhým přístupem je předat objekt blob XML obsahující hodnoty a použít vestavěnou funkci XML serveru SQL Server. Oba tyto přístupy jsou demonstrovány pomocí výkonnostních metrik v tomto odkazu a nevyžadují žádné dynamické SQL.

Pokud byste používali SQL Server 2008, byly by parametry tabulky tou správnou cestou – to je třetí přístup, který demonstruji v tomto odkazu, který vychází nejlépe.



  1. MySQL:vyberte položky, které nejsou v seznamu

  2. Nalezení záznamu s maximální hodnotou v SQL

  3. Přidání sekund k datetime v MySQL

  4. BCrypt Ověřte uložený hash hesla