Dynamiczny SQL - EXEC (@SQL) a EXEC SP_EXECUTESQL (@SQL)


95

Jakie są rzeczywiste wady i zalety wykonywania dynamicznego polecenia SQL w procedurze składowanej w programie SQL Server przy użyciu

EXEC (@SQL)

przeciw

EXEC SP_EXECUTESQL @SQL

?

Odpowiedzi:


96

sp_executesqljest bardziej prawdopodobne, że będzie promować ponowne wykorzystanie planu zapytań. Podczas używania sp_executesqlparametry są wyraźnie identyfikowane w sygnaturze wywołania. Ten wspaniały artykuł opisuje ten proces .

Często cytowanym odniesieniem dla wielu aspektów dynamicznego sql jest książka Erlanda Sommarskoga, którą trzeba przeczytać: „ Klątwa i błogosławieństwa dynamicznego SQL ”.


21

Dużą zaletą SP_EXECUTESQL jest to, że pozwala tworzyć sparametryzowane zapytania, co jest bardzo dobre, jeśli zależy Ci na wstrzykiwaniu SQL.


1
Nie sądzę, że można bez niego sparametryzować dynamiczny sql?
DJ.

EXEC ('SELECT * FROM FOO WHERE ID =?', 123) zastąpi symbol zastępczy parametru „?” z wartością 123, a następnie wykonaj zapytanie, zwracając wynik dla SELECT * FROM FOO WHERE ID = 123
Peter Wone

1
Ups, ta składnia jest dostępna tylko dla połączonych serwerów.
Peter wygrał

1
Absolutnie jeden z największych powodów, dla których warto używać sp_executesql podczas dynamicznego budowania zapytania, aby zapobiec iniekcji sql.
Steven Rogers

5

Artykuł Microsoftu Using sp_executesql zaleca używanie sp_executesqlzamiast executeinstrukcji.

Ponieważ ta procedura składowana obsługuje podstawianie parametrów , sp_executesql jest bardziej wszechstronna niż EXECUTE; a ponieważ sp_executesql generuje plany wykonania, które z większym prawdopodobieństwem zostaną ponownie wykorzystane przez SQL Server, sp_executesql jest bardziej wydajne niż EXECUTE.

A więc na wynos: nie używaj executeinstrukcji . Użyj sp_executesql.


7
Twoje dania na wynos nie zawsze są ważne. Są sytuacje, w których nie ma premii za wydajność przy użyciu sp_executesql, ale możesz chronić swój kod przed atakiem sql injection. Czasami po prostu nie możesz użyć sp_executesql tak, jak używasz exec, więc ... ktoś powiedział - nie ma srebrnej kuli. Zgadzam się.
OzrenTkalcecKrznaric

Tak, Microsoft powinien był to określić jako „bardziej prawdopodobne, że będzie skuteczny”. Będąc w branży od kilku lat, widziałem przypadki, w których sp_executesqlnie można ich zastąpić execute. Być może powinienem ująć to, co staram się podkreślić, jako: Używaj sp_executesqlzamiast tego, execute kiedy to możliwe .
Gan,

2

W dzisiejszych czasach zawsze używałbym sp_executesql, wszystko to naprawdę jest opakowaniem dla EXEC, które obsługuje parametry i zmienne.

Jednak nie zapomnij o OPCJI RECOMPILE podczas strojenia zapytań w bardzo dużych bazach danych, zwłaszcza gdy masz dane rozłożone na więcej niż jedną bazę danych i używasz OGRANICZENIA w celu ograniczenia skanowania indeksów.

O ile nie użyjesz OPCJI RECOMPILE, serwer SQL podejmie próbę utworzenia planu wykonania zapytania „jeden rozmiar dla wszystkich” i będzie przeprowadzał pełne skanowanie indeksu przy każdym uruchomieniu.

Jest to znacznie mniej wydajne niż wyszukiwanie i oznacza, że ​​potencjalnie skanuje całe indeksy, które są ograniczone do zakresów, których nawet nie pytasz: @


-2
  1. Zadeklaruj zmienną
  2. Ustaw go za pomocą polecenia i dodaj dynamiczne części, takie jak użyj wartości parametrów sp (tutaj @IsMonday i @IsTuesday są parametrami sp)
  3. wykonać polecenie

    declare  @sql varchar (100)
    set @sql ='select * from #td1'
    
    if (@IsMonday+@IsTuesday !='')
    begin
    set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
    end
    exec( @sql)
    

15
To jest otwarte na wstrzyknięcie SQL, jeśli umieścisz np. "A '; DROP DATABASE DATABASE_NAME; GO;';" w zmiennej @IsMonday
Erik A. Brandstadmoen

czy jest podatny na uszkodzenie sql, jeśli @IsMonday jest int?
Vikas Rana

@VikasRana @IsMonday nie może być intw dynamicznym języku SQL. Zauważ, że @sql jest zadeklarowane jako varcharlubnvarchar
Weihui Guo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.