Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak przekazać zmienną zawierającą listę do dynamicznego zapytania SQL?

Po prostu

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

Albo, co jest lepsze

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;
  • Dlaczego pojawia się ten błąd?

Ponieważ naprawdę przekazujesz za dużo parametrów, więcej niż potrzeba, aby to zrozumieć, uruchom to zapytanie i zobacz, co tak naprawdę przekazujesz do swojej funkcji

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

który zwróci (i to właśnie próbujesz wykonać)

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

zamiast (czego potrzebujesz)

SELECT 'select id from  [dbo].[CSVToTable] ('''[email protected]+''')';
  • Ok, ale dlaczego sp_executesql jest lepszy niż exec ?

Po prostu EXEC zmusi Cię do połączenia wszystkich zmiennych w jeden ciąg, to najgorsza rzecz w tym, a to sprawi, że Twój kod będzie w pełni otwarty na wstrzyknięcie SQL . Zobacz Bad Habits to Kick : Using EXEC() instead of sp_executesql , nie oznacza to, że sp_executesql jest w 100% bezpieczny, ale pozwala na parametryzację wyrażeń podczas gdy EXEC() nie, dlatego jest bezpieczniejszy niż EXEC pod względem wstrzykiwania SQL .

Wreszcie, odkąd oznaczysz a nie określasz wersji, sugeruję użycie SPLIT_STRING() funkcja (2016+) rathar niż twoja, a jeśli nie masz wersji 2016+, stwórz własną bez użycia WHILE pętla, aby uzyskać lepszą wydajność, ponieważ WHILE pętla będzie działać wolno, dlatego należy jej unikać.

Przykłady:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy możliwe jest wykonanie pliku tekstowego z zapytania SQL?

  2. Jak uruchomić wiele poleceń SQL w jednym połączeniu SQL?

  3. Utwórz datę z dnia, miesiąca i roku za pomocą T-SQL

  4. jak znaleźć wersję i edycję instancji serwera sql za pośrednictwem rejestru?

  5. Usuń znaki rozszerzone ASCII od 128 (SQL)