Каковы реальные плюсы и минусы выполнения динамической команды SQL в хранимой процедуре в SQL Server с использованием
EXEC (@SQL)
против
EXEC SP_EXECUTESQL @SQL
?
Каковы реальные плюсы и минусы выполнения динамической команды SQL в хранимой процедуре в SQL Server с использованием
EXEC (@SQL)
против
EXEC SP_EXECUTESQL @SQL
?
Ответы:
sp_executesql
с большей вероятностью будет способствовать повторному использованию плана запроса. При использовании sp_executesql
параметры явно указываются в вызывающей сигнатуре. Эта отличная статья описывает этот процесс .
Часто цитируемый справочник по многим аспектам динамического SQL - это то, что Эрланд Соммарског должен прочитать: « Проклятие и благословение динамического SQL ».
Важность SP_EXECUTESQL заключается в том, что он позволяет создавать параметризованные запросы, что очень хорошо, если вы заботитесь о SQL-инъекции.
В статье Microsoft по использованию sp_executesql рекомендуется использовать sp_executesql
вместо execute
оператора.
Поскольку эта хранимая процедура поддерживает подстановку параметров , процедура sp_executesql более универсальна, чем EXECUTE; и поскольку процедура sp_executesql генерирует планы выполнения, которые с большей вероятностью будут повторно использоваться SQL Server, процедура sp_executesql более эффективна, чем EXECUTE.
Итак, вывод: не используйте execute
заявление . Используйте sp_executesql
.
sp_executesql
их нельзя было использовать для замены execute
. Возможно, мне следует выразить мысль, которую я пытаюсь подчеркнуть, как: «Используйте sp_executesql
вместо того, execute
когда это возможно» .
В наши дни я бы всегда использовал sp_executesql, все, что на самом деле является оболочкой для EXEC, которая обрабатывает параметры и переменные.
Однако не забывайте о OPTION RECOMPILE при настройке запросов в очень больших базах данных, особенно если у вас есть данные, охватывающие более одной базы данных, и вы используете CONSTRAINT для ограничения сканирования индекса.
Если вы не используете OPTION RECOMPILE, SQL-сервер попытается создать план выполнения «один размер для всех» для вашего запроса и будет запускать полное сканирование индекса при каждом его запуске.
Это намного менее эффективно, чем поиск, и означает, что он потенциально сканирует целые индексы, которые ограничены диапазонами, которые вы даже не запрашиваете: @
выполнить команду
declare @sql varchar (100)
set @sql ='select * from #td1'
if (@IsMonday+@IsTuesday !='')
begin
set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
end
exec( @sql)
int
в динамическом SQL. Обратите внимание, что @sql объявлен как varchar
ornvarchar