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 serwer-sql
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: