Published on

January 1, 2020

Понимание sp_executesql в SQL Server

sp_executesql – это встроенная хранимая процедура в SQL Server, которая позволяет выполнять динамически созданные SQL-запросы или пакеты. Эта процедура является полезным инструментом для преодоления различных проблем в SQL-программировании, таких как определение отображаемых столбцов в отчетах. В этой статье мы рассмотрим синтаксис, использование и преимущества sp_executesql.

Синтаксис

Синтаксис для sp_executesql выглядит следующим образом:

sp_executesql @stmt, N'@parametername1_datatype,@parametername2_datatype,@parameternameN_datatype', @parametername1 = 'Value1', @parametername2 = 'Value2', @parameternameN = 'ValueN'

Параметр @stmt указывает динамически созданный SQL-запрос или пакет. Тип данных этого параметра должен быть Unicode-строками, поэтому нам нужно добавить префикс N или использовать переменные с типом данных nvarchar или nchar. Параметр @parameternameN_datatype определяет имя параметра и тип данных, используемый в динамически созданных SQL-запросах. Мы можем присваивать значения этим параметрам с помощью выражения @parameternameN=’ValueN’.

Пример

Рассмотрим пример, в котором мы извлекаем данные из таблицы Person в базе данных AdventureWorks. Мы хотим отобразить определенные столбцы и отфильтровать данные на основе столбца PersonType.

DECLARE @SqlStatement AS NVARCHAR(1000)
DECLARE @ColNames AS NVARCHAR(100)
SET @ColNames = N'FirstName, MiddleName, LastName';
SET @SqlStatement = 'SELECT ' + @ColNames + ' FROM Person.Person WHERE PersonType=@PerType'
EXECUTE sp_executesql @SqlStatement, N'@PerType nchar(2)', @PerType = 'EM'

В этом примере мы присваиваем динамически созданный SQL-запрос переменной @SqlStatement. Переменная @ColNames указывает имена столбцов, которые будут отображаться в наборе результатов. Мы фильтруем данные на основе параметра @PerType, который имеет тип данных nchar(2) и фильтрует данные, где столбец PersonType равен “EM”. Затем выполняется запрос, и в набор результатов будут включены только указанные столбцы.

Использование параметра OUTPUT

sp_executesql также позволяет нам возвращать результат выполнения динамически созданного SQL-запроса или пакета с помощью параметра OUTPUT. Рассмотрим пример, в котором мы подсчитываем количество строк в таблице PersonPhone и присваиваем результат переменной:

DECLARE @SqlStatement AS NVARCHAR(1000)
DECLARE @PhoneIdType AS INT
DECLARE @Result AS INT
SET @SqlStatement = 'SELECT @RowNumber=COUNT(PhoneNumber) FROM Person.PersonPhone WHERE PhoneNumberTypeID=@PhoneType'
SET @PhoneIdType = 1
EXEC sp_executesql @SqlStatement, N'@PhoneType INT, @RowNumber INT OUTPUT', @PhoneType = @PhoneIdType, @RowNumber = @Result OUTPUT
SELECT @Result AS [TableRowNumber]

В этом примере мы указываем параметр @RowNumber как параметр OUTPUT и присваиваем его значение параметру @Result. Это позволяет нам получить количество строк из динамически созданного запроса.

sp_executesql против оператора EXEC

Оператор EXEC – это еще один вариант выполнения динамических SQL-запросов. Однако sp_executesql имеет некоторые преимущества перед оператором EXEC:

  • sp_executesql имеет возможность повторного использования кэшированных планов запросов, что помогает снизить затраты на компиляцию запросов.
  • sp_executesql позволяет генерировать параметризованные динамические запросы, что делает его более безопасным от атак SQL-инъекций.

С другой стороны, оператор EXEC не поддерживает параметризацию и может создавать новые планы запросов для каждого выполнения, что потенциально потребляет больше ресурсов и вызывает проблемы с производительностью.

Заключение

В этой статье мы рассмотрели процедуру sp_executesql в SQL Server. Мы узнали о ее синтаксисе, использовании и преимуществах по сравнению с оператором EXEC. sp_executesql – это мощный инструмент для выполнения динамически созданных SQL-запросов или пакетов, и он предлагает такие преимущества, как повторное использование планов запросов и защита от атак SQL-инъекций. Понимание и эффективное использование sp_executesql могут значительно улучшить возможности SQL-программирования.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.