Czy sp_executesql może być domyślnie skonfigurowany / używany?

10

Patrzę na aplikację, która korzysta z bardzo dynamicznych zapytań SQL przeciwko SQL Server. Patrząc na zapytania, które są konstruowane w bardzo dziwny i skomplikowany sposób, ale to inna historia, mówię to, aby podać dobry powód, dla którego nie jestem w stanie (zbyt głupio) samemu się dowiedzieć ... Nie widzę dowolny kod, w którym zapytania są opakowane sp_executesql.

Ale kiedy śledzę, widzę, że wiele zapytań jest zapakowanych sp_executesql. Całe rozwiązanie aplikacyjne w ogóle nie zawiera polecenia sp_executesql.

Zastanawiałem się więc, czy istnieje jakaś konfiguracja, której jeszcze nie znam, która zmusza oprogramowanie do domyślnego zawijania zapytań sp_executesql?

Co może powodować takie zachowanie?

Magier
źródło

Odpowiedzi:

11

Powodem pakowania instrukcji SQL sp_executesqljest ustawienie SqlCommand.Commandtypewłaściwości i przekazanie dowolnych parametrów do polecenia.

SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.StoredProcedure;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Powyższy kod kończy się następującym T-SQL:

exec proc1 @param1=1
SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.Text;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();

Ten kod kończy się wykonaniem następującego T-SQL:

exec sp_executesql N'proc1',N'@param1 int',@param1=1

Dodatek 23.12.15: Przy użyciu CommandType.Textpolecenia wyniki są podobne: jak tylko parametr zostanie dodany do obiektu polecenia, .NET otoczy całe zapytanie sp_executesqli przekaże mu parametry.

Dodanie: po głębszym zanurzeniu się sp_executesql, wąchanie parametrów i planowanie buforowania tego zachowania klas .NET ma sens, aby uniknąć kompilacji zapytań i liczby planów. Jest więc zasadniczo zaprojektowany, aby ogólnie zapewnić lepszą wydajność SQL Server, a jednocześnie może prowadzić do słabej wydajności niektórych zapytań (problem z węszeniem parametrów), które są używane z innymi wartościami parametrów niż początkowo utworzony plan zapytań.

Widzieć:

Powyższy przykład został utworzony przy użyciu .NET Framework 4.5 i SQL Server 2008 Developer Edition.

Magier
źródło
5

Jeśli jest to aplikacja .NET, najprawdopodobniej jest to wywołanie SqlCommand.ExecuteReader () . Według głównej strony klasy SqlCommand , w siatce opisów metod w sekcji „Uwagi”, w części ExecuteReader mówi:

Wykonuje polecenia zwracające wiersze. Aby zwiększyć wydajność, ExecuteReader wywołuje polecenia przy użyciu procedury przechowywanej w systemie Transact-SQL sp_executesql . Dlatego narzędzie ExecuteReader może nie mieć oczekiwanego efektu, jeśli jest używane do wykonywania poleceń, takich jak instrukcje Transact-SQL SET.

Nie mam teraz czasu, aby to przetestować, aby potwierdzić ich opis, ale powinno być łatwo stworzyć prostą aplikację konsoli, która wykonuje bardzo proste wywołanie, przekazując tekst zapytania i zawierając parametr dostarczony z parametrem SqlParameter. Domyślam się, że ExecuteNonQueryi ExecuteScalarrównież użyć sp_executesqlponieważ pozwalają one również na przekazywanie parametrów, więc dlaczego by nie być inna ścieżka do jak te są wykonywane?

Solomon Rutzky
źródło