Выполнение динамических T-SQL инструкций в Microsoft SQL Server
В данном материале мы поговорим о выполнении динамического T-SQL кода, Вы узнаете, как сформировать текстовую строку, содержащую SQL инструкцию, и запустить ее на выполнение в Microsoft SQL Server.
Динамический код в Microsoft SQL Server
Microsoft SQL Server позволяет выполнять SQL инструкции, сформированные динамически, так как иногда без этого просто не обойтись. Например, для того чтобы динамически выполнять инструкции, которые с первого взгляда кажутся статическими. К примеру, оператор PIVOT, его синтаксис, предполагает вручную перечислять выходные столбцы, количество и название которых заранее нам могут быть просто не известны. Но мы можем сформировать динамическую инструкцию, которая будет автоматически узнавать и подставлять все необходимые нам значения в SQL запрос, и тем самым нам уже не нужно знать и тем более вручную указывать выходные столбцы, в случае с оператором PIVOT, кстати, ранее я уже приводил пример реализации динамического PIVOT.
Динамическая SQL инструкция – это просто текстовая строка, которая после преобразования и подставки всех значений, исполняется SQL сервером как обычная SQL инструкция.
Таким образом, чтобы сформировать динамическую SQL инструкцию, необходимо просто сформировать текстовую строку с указанием необходимых переменных, значения которых Вы хотите подставлять, или произвести конкатенацию строк с переменными, используя оператор + (плюс).
В Microsoft SQL Server существует два способа запускать на выполнения строки, содержащие SQL инструкции, это: команда EXECUTE и системная хранимая процедура sp_executesql.
Исходные данные для примеров
Перед тем как переходить к рассмотрению примеров выполнения динамических инструкций, давайте создадим тестовые данные, например, таблицу TestTable, и добавим в нее несколько строк.
Команда EXECUTE в T-SQL
EXECUTE (сокращенно EXEC) – команда для запуска хранимых процедур и SQL инструкций в виде текстовых строк.
Перед тем как переходить к примерам, следует отметить, что использование динамического кода с использованием команды EXEC – это не безопасно! Дело в том, что для того чтобы сформировать динамическую SQL инструкцию, необходимо использовать переменные для динамически изменяющихся значений. Так вот, если эти значения будут приходить от клиентского приложения, т.е. от пользователя, злоумышленники могут передать и, соответственно, внедрить в нашу инструкцию вредоносный код в виде текста, а мы его просто исполним в БД, думая, что нам передали обычные параметры. Поэтому все такие значения следует очень хорошо проверять, перед тем как подставлять в инструкцию.
Пример использования EXEC в T-SQL
Сейчас мы с Вами сформируем динамический SQL запрос, текст которого мы сохраним в переменной, и затем выполним его с помощью команды EXEC.
Текст запроса будет храниться в переменной @SQL_QUERY, в переменной @Var1 будет храниться значение, которое мы будем подставлять в наш запрос, для того чтобы этот запрос стал динамическим (в нашем случае мы вручную присвоим статическое значение в переменную, хотя это значение можно узнавать, например, с помощью запроса или каких-то вычислений).
Для формирования строки мы будет использовать конкатенацию строк, а именно оператор + (плюс), только стоит понимать, что в этом случае выражения, участвующие в операции, должны иметь текстовый тип данных. Переменная @Var1 у нас будет иметь тип данных INT, поэтому, чтобы соединить ее со строкой, мы предварительно преобразуем ее значение к типу данных VARCHAR.
Для наглядности того, какой именно SQL запрос у нас получился, мы просто посмотрим, что у нас хранится в переменной @SQL_QUERY инструкцией SELECT.
Хранимая процедура sp_executesql в T-SQL
sp_executesql – это системная хранимая процедура Microsoft SQL Server, которая выполняет SQL инструкции. Эти инструкции могут содержать параметры, тем самым делая их динамическими.
Процедура sp_executesql имеет несколько параметров, первым параметром указывается текст SQL инструкции, вторым объявляются переменные, третий и все последующие — это передача значений для переменных в процедуру и, соответственно, подстановка в нашу инструкцию.
Все параметры процедуры sp_executesql необходимо передавать в формате Unicode (тип данных строк должен быть NVARCHAR).
Пример использования sp_executesql в T-SQL
В этом примере итоговый результат у нас будет точно таким же, как и в примере с EXEC, только динамические значения, у нас это переменная @Var1, мы объявим и передадим в виде параметров хранимой процедуры sp_executesql.
У меня на этом все, надеюсь, материал был Вам интересен и полезен, если Вас интересуют другие возможности языка T-SQL, то рекомендую посмотреть мои видеокурсы по T-SQL, в которых используется последовательная методика обучения специально для начинающих, пока!
Метод Execute (объект Connection ADO)
выполняет указанный запрос, SQLную инструкцию, хранимую процедуру или зависящий от поставщика текст.
Синтаксис
Возвращаемое значение
Параметры
CommandText
строковое значение, содержащее инструкцию SQL, хранимую процедуру, URL-адрес или определяемый поставщиком текст для выполнения. при необходимости можно использовать имена таблиц, но только в том случае, если поставщик SQL осведомлен. например, если используется имя таблицы «customers», ADO автоматически добавляет стандартный синтаксис SQL Select для формирования и передачи «Select * FROM customers» в качестве Transact-SQL инструкции поставщику.
RecordsAffected
Необязательный параметр. Длинная переменная, к которой поставщик возвращает количество записей, затронутых операцией.
Не используйте значения Коммандтипинум для Адкмдфиле или Адкмдтабледирект с Execute. Эти значения можно использовать только в качестве параметров с методами методов запроса Open (ADO Recordset) и Requery для набора записей.
Комментарии
Возвращаемый объект набора записей всегда является однонаправленным курсором только для чтения. Если требуется объект набора записей с дополнительными функциональными возможностями, сначала создайте объект набора записей с параметрами требуемого свойства, а затем используйте метод объекта набора записей (ADO Recordset) для выполнения запроса и возврата требуемого типа курсора.
содержимое аргумента CommandText зависит от поставщика и может быть стандартным SQL синтаксисом или любым специальным форматом команды, поддерживаемым поставщиком.
Когда эта операция завершается, будет выдано событие Ексекутекомплете.
URL-адреса, использующие схему HTTP, автоматически вызывают поставщик OLE DB Майкрософт для публикации в Интернете. Дополнительные сведения см. в разделе абсолютные и относительные URL-адреса.
Функция SQLExecute
Соответствия
Представленная версия: соответствие стандартам ODBC 1,0: ISO 92
Сводка
SQLExecute выполняет подготовленную инструкцию, используя текущие значения переменных маркера параметра, если в инструкции существуют маркеры параметров.
Синтаксис
Аргументы
статеменсандле
Входной Маркер инструкции.
Возвращаемое значение
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, SQL_INVALID_HANDLE или SQL_PARAM_DATA_AVAILABLE.
Диагностика
Значение данных, возвращаемое для параметра, привязанного как SQL_PARAM_INPUT_OUTPUT или SQL_PARAM_OUTPUT, не может быть преобразовано в тип данных, определяемый аргументом ValueType в SQLBindParameter.
(Если не удалось преобразовать значения данных для одной или нескольких строк, но одна или несколько строк были успешно возвращены, эта функция возвращает SQL_SUCCESS_WITH_INFO.)
Арифметическое выражение, вычисленное для входного/выходного или выходного параметра, привело к делению на нуль.
* Статементтекст содержал параметр интервала с более чем одним полем, которое при преобразовании в числовой тип данных столбца не имело представления числового типа данных.
* статементтекст содержал данные параметров, которые были присвоены интервалу SQL типу, и не было представления значения типа C в поле interval SQL type.
назначение входного/выходного или выходного параметра, который был точным числом или интервалом, SQL тип с типом interval C привел к утрате значащих цифр.
Если входной/выходной или выходной параметр был назначен структуре интервала C, в структуре данных интервала отсутствовало представления данных.
Курсор был открыт в статеменсандле.
(DM) SQLExecute, SQLExecDirect или SQLMoreResults были вызваны для статеменсандле и возвращены SQL_PARAM_DATA_AVAILABLE. Эта функция была вызвана до получения данных для всех потоковых параметров.
(DM) вызывается асинхронно исполняемая функция (не эта одна) для статеменсандле и все еще выполнялась при вызове этой функции.
(DM) SQLExecute, SQLExecDirect, SQLBulkOperations или SQLSetPos были вызваны для статеменсандле и возвращены SQL_NEED_DATA. Эта функция была вызвана перед отправкой данных для всех параметров или столбцов данных, выполняемых во время выполнения.
(DM) статеменсандле не был подготовлен.
Значение параметра, заданное с помощью SQLBindParameter, не является пустым указателем; тип данных C — SQL_C_BINARY или SQL_C_CHAR; и значение длины параметра было меньше 0, но не было SQL_NTS, SQL_NULL_DATA, SQL_DEFAULT_PARAM или SQL_DATA_AT_EXEC или меньше или равно SQL_LEN_DATA_AT_EXEC_OFFSET.
SQLExecute может возвращать любое значение SQLSTATE, которое может быть возвращено SQLPrepare, в зависимости от того, когда источник данных оценивает инструкцию SQL, связанную с инструкцией.
Комментарии
SQLExecute выполняет инструкцию, подготовленную SQLPrepare. После того как приложение обрабатывает или отклоняет результаты из вызова SQLExecute, приложение может снова вызвать SQLExecute с новыми значениями параметров. Дополнительные сведения о подготовленном выполнении см. в разделе подготовленное выполнение.
если источник данных находится в режиме фиксации вручную (требует явной инициации транзакции) и транзакция еще не запущена, драйвер инициирует транзакцию перед отправкой инструкции SQL. Дополнительные сведения см. в статье о транзакциях.
Если SQLExecute встречает параметр данных при выполнении, он возвращает SQL_NEED_DATA. Приложение отправляет данные с помощью метод SQLParamData и SQLPutData. См. раздел SQLBindParameter, метод SQLParamData, SQLPutDataи Отправка длинных данных.
Если SQLExecute выполняет инструкцию обновления, вставки или удаления, которая не влияет ни на какие строки в источнике данных, вызов SQLExecute возвращает SQL_NO_DATA.
если значение атрибута оператора SQL_ATTR_PARAMSET_SIZE больше 1, а инструкция SQL содержит по крайней мере один маркер параметра, SQLExecute выполняет инструкцию SQL один раз для каждого набора значений параметров в массивах, на которые указывает аргумент * параметервалуептр в вызовах SQLBindParameter. Дополнительные сведения см. в разделе массивы значений параметров.
Если закладки включены и выполняется запрос, который не поддерживает закладки, драйвер должен попытаться привести среду к той, которая поддерживает закладки, изменив значение атрибута и возвращая SQLSTATE 01S02 (значение параметра изменено). Если атрибут не может быть изменен, драйвер должен возвращать значение SQLSTATE HY024 (недопустимое значения атрибута).
при использовании пулов соединений приложение не должно выполнять инструкции SQL, которые изменяют базу данных или контекст базы данных, например инструкцию USE database в SQL Server, которая изменяет каталог, используемый источником данных.
EXECUTE (Transact-SQL)
Выполняет строку команды или символьную строку в пакете Transact-SQL либо один из следующих модулей: системная хранимая процедура, определяемая пользователем хранимая процедура, хранимая процедура CLR, скалярная, определяемая пользователем функция или расширенная хранимая процедура. Инструкция EXECUTE может использоваться для отправки транзитных команд на связанные серверы. или явно указывать контекст, в котором выполняется команда. Метаданные для результирующего набора могут быть определены с помощью параметров WITH RESULT SETS.
Прежде чем передавать инструкции EXECUTE строку символов, выполните ее проверку. Ни в коем случае не запускайте на выполнение команду, которая сформирована на основе данных, введенных пользователем, и не проверена.

Синтаксис
В следующем блоке кода показан синтаксис в SQL Server 2019. Также можно посмотреть раздел Синтаксис в SQL Server 2017 и более ранних.
В следующем блоке кода показан синтаксис в SQL Server 2017 и более ранних версиях. Также можно посмотреть раздел Синтаксис в SQL Server 2019.
Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.
Аргументы
@return_status
Необязательная целочисленная переменная, в которой сохраняется состояние возврата из модуля. Этот аргумент должен быть объявлен в пакете, хранимой процедуре или функции, прежде чем его можно будет указать в инструкции EXECUTE.
Если используется для вызова скалярной, определяемой пользователем функции, переменная @return_status может иметь любой скалярный тип данных.
module_name
Полное или неполное имя вызываемой хранимой процедуры или скалярной пользовательской функции. Имена модулей должны соответствовать правилам для идентификаторов. В именах расширенных хранимых процедур учитывается регистр, вне зависимости от параметров сортировки сервера.
Допускается выполнение модуля, созданного в другой базе данных, если пользователь, выполняющий этот модуль, является его владельцем или имеет соответствующие разрешения на его выполнение в этой базе данных. Модуль может быть выполнен на другом сервере SQL Server, если пользователь, запускающий модуль на выполнение, имеет соответствующие разрешения на этом сервере (удаленный доступ) и на выполнение модуля в этой базе данных. Если указано имя сервера, а имя базы данных не указано, компонент Компонент SQL Server Database Engine ищет модуль в базе данных пользователя по умолчанию.
number
Область применения: SQL Server 2008 и более поздних версий
Необязательный целочисленный аргумент, используемый для группирования одноименных процедур. Этот аргумент не предназначен для расширенных хранимых процедур.
В будущей версии Microsoft SQL Server этот компонент будет удален. Избегайте использования этого компонента в новых разработках и запланируйте изменение существующих приложений, в которых он применяется.
Дополнительные сведения о группах процедур см. в статье CREATE PROCEDURE (Transact-SQL).
@module_name_var
Имя локально определенной переменной, которая содержит имя модуля.
Это может быть переменная, содержащая имя скомпилированной в собственном коде скалярной определяемой пользователем функции.
@parameter
Параметр для module_name, как определено в модуле. Имена аргументов должны предваряться символом (@). Если используется в формате @parameter_name=value, то имена параметров и констант могут указываться не в том порядке, в котором они определены в модуле. Однако если какой-либо из параметров указан в формате @parameter_name=value, то все последующие параметры должны быть указаны в том же формате.
По умолчанию параметры могут допускать значения NULL.
value
Значение параметра, передаваемое модулю или транзитной команде. Если имена параметров не указаны, значения параметров должны указываться в том же порядке, в каком они определены в модуле.
При выполнении транзитных команд для связанных серверов порядок значений параметров зависит от поставщика OLE DB связанного сервера. Большинство поставщиков OLE DB привязывают значения к аргументам слева направо.
Если значение параметра является именем объекта, символьной строкой или предваряется именем базы данных или схемы, это значение целиком должно быть заключено в одинарные кавычки. Если значение параметра является ключевым словом, оно должно быть заключено в двойные кавычки.
Если вы передаете одно слово, которое не начинается с @ и не заключено в кавычки (например, если вы забудете @ в имени параметра), слово рассматривается как строка типа nvarchar, несмотря на отсутствие кавычек.
Если в модуле определено значение по умолчанию, пользователь может вызвать модуль без указания этого параметра.
Значение по умолчанию может быть равно NULL. Как правило, действие, которое должно быть выполнено в этом случае, указывается в определении модуля.
@variable
Переменная, в которой сохраняется или возвращается аргумент.
OUTPUT
Указывает, что модуль или командная строка возвращает параметр. Совпадающий параметр модуля или командной строки также должен быть создан с ключевым словом OUTPUT. Это ключевое слово следует указывать для переменной курсора, если она передается в качестве аргумента.
Если value определен как OUTPUT модуля, выполняемого для связанного сервера, то любые изменения в соответствующем параметре @parameter, произведенные поставщиком OLE DB, по окончании выполнения модуля будут скопированы обратно в переменную.
Если используются параметры OUTPUT и предполагается использовать возвращаемые значения в других инструкциях вызываемого пакета или модуля, значение параметра должно передаваться в виде переменной, то есть @parameter = @variable. Выполнить модуль, указав OUTPUT для параметра, который не определен в модуле как параметр OUTPUT, нельзя. Константы в качестве аргументов OUTPUT в модуль не передаются, а для возврата аргумента необходимо указывать имя переменной. Перед выполнением процедуры для переменной должен быть объявлен тип данных и присвоено значение.
Если EXECUTE выполняет удаленную хранимую процедуру или транзитную команду к связанному серверу, то параметры OUTPUT не могут иметь типы данных больших объектов (LOB).
Возвращаемые аргументы могут иметь любой тип, кроме типов данных LOB.
DEFAULT
Определяет значение параметра по умолчанию, как определено в модуле. Если в модуле для параметра не определено значения по умолчанию, а при вызове для этого параметра ни значение, ни ключевое слово DEFAULT не указаны, выдается ошибка.
[N] ‘tsql_string‘
Строковая константа. tsql_string может иметь любой тип данных nvarchar или varchar. Если указано «N», строка интерпретируется как тип данных nvarchar.
AS
Определяет контекст, в котором выполняется инструкция.
Имя_для_входа
Область применения: SQL Server 2008 и более поздних версий
Указывает, что воплощаемым контекстом является имя входа, область олицетворения — сервер.
Пользователь
Определяет контекст для олицетворения пользователя в текущей базе данных. Область олицетворения ограничена текущей базой данных. При переключении контекста на пользователя базы данных разрешения уровня сервера этого пользователя не наследуются.
Пока активно переключение контекста на пользователя базы данных, любая попытка доступа к ресурсам за ее пределами вызовет ошибку выполнения инструкции. Это относится к инструкциям USE database, распределенным запросам, а также запросам, содержащим ссылки на другие базы данных по идентификаторам, состоящим из трех или четырех элементов.
‘name‘
Допустимое имя пользователя или имя входа. Аргумент name должен принадлежать предопределенной роли сервера sysadmin либо быть участником в базе данных sys.database_principals или sys.server_principals соответственно.
В качестве аргумента name не может быть указана встроенная учетная запись (например NT AUTHORITY\LocalService, NT AUTHORITY\NetworkService или NT AUTHORITY\LocalSystem).
Дополнительные сведения см. в разделе Указание имени пользователя или имени входа далее.
[N] ‘command_string‘
Строковая константа, содержащая транзитную команду, передаваемую связанному серверу. Если указано «N», строка интерпретируется как тип данных nvarchar.
AT linked_server_name
Область применения: SQL Server 2008 и более поздних версий
Указывает, что command_string выполняется для linked_server_name, а результаты, при их наличии, возвращаются клиенту. Значение linked_server_name должно указывать на существующее определение связанного сервера на локальном сервере. Определение связанного сервера производится при помощи хранимой процедуры sp_addlinkedserver.
WITH
Возможные параметры выполнения. Параметры RESULT SETS нельзя указывать в инструкции INSERT. EXEC.
AT DATA_SOURCE data_source_name Применимо к: SQL Server 2019 (15.x) и более поздних версий.
Указывает, что command_string выполняется для data_source_name, а результаты, при их наличии, возвращаются клиенту. data_source_name должно ссылаться на существующее определение EXTERNAL DATA SOURCE (внешнего источника данных) в базе данных. Поддерживаются только источники данных, указывающие на SQL Server. Кроме того, для SQL Server поддерживаются источники данных кластера больших данных, которые указывают на пул вычислений, пул данных или пул носителей. Источники данных определяются с помощью CREATE EXTERNAL DATA SOURCE (создание внешнего источника данных).
WITH
Возможные параметры выполнения. Параметры RESULT SETS нельзя указывать в инструкции INSERT. EXEC.
| Термин | Определение |
|---|---|
| RECOMPILE | Инициирует перекомпиляцию нового плана, его использование и удаление после выполнения модуля. Если для модуля имеется существующий план запроса, то он остается в кэше. Следует указывать этот параметр в тех случаях, когда передаются нетипичные аргументы или если данные существенно изменились. Он не предназначен для расширенных хранимых процедур. Рекомендуется реже пользоваться этим параметром, поскольку он очень ресурсоемок. Примечание. Использовать параметр WITH RECOMPILE при вызове хранимой процедуры, для которой применяется синтаксис OPENDATASOURCE, невозможно. Параметр WITH RECOMPILE не учитывается при указании четырехкомпонентного имени объекта. Примечание. Скомпилированные в собственном коде скалярные определяемые пользователем функции не поддерживают RECOMPILE. Если потребуется выполнить повторную компиляцию, используйте процедуру sp_recompile (Transact-SQL). |
| RESULT SETS UNDEFINED | Применимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure. Этот параметр не дает гарантии, какие результаты, если они есть, будут возвращены. Определение также не предоставляется. Инструкция выполняется без ошибок, независимо от того, возвращаются ли какие-либо результаты. RESULT SETS UNDEFINED — действие по умолчанию, если не указан result_sets_option. Для интерпретируемых скалярных определяемых пользователем функций и скомпилированных в собственном коде скалярных определяемых пользователем функций этот параметр не работает, так как функции никогда не возвращают результирующий набор. |
| RESULT SETS NONE | Применимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure. Гарантирует, что выполняемая инструкция не вернет никаких результатов. Если возвращены какие-либо результаты, то пакет отменяется. Для интерпретируемых скалярных определяемых пользователем функций и скомпилированных в собственном коде скалярных определяемых пользователем функций этот параметр не работает, так как функции никогда не возвращают результирующий набор. |
| Применимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure. Этот параметр всегда приводит к ошибке для скомпилированных в собственном коде скалярных определяемых пользователем функций, поскольку функции никогда не возвращают результирующий набор. |
Применимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure.
Описывает результирующие наборы, возвращенные выполненными инструкциями. Предложения result_sets_definition имеют следующий смысл
| Термин | Определение |
|---|---|
| < Фактический результирующий набор, возвращаемый во время выполнения, может отличаться от результата, определенного в предложении WITH RESULT SETS по одному из следующих признаков: числом результирующих наборов, числом столбцов, именами столбцов, допустимостью значений NULL и типами данных. Если отличается число результирующих наборов, возникнет ошибка, и пакет будет отменен. RemarksЕсли модуль вызывает другой модуль, выполняет управляемый код модуля среды CLR, определяемого пользователем типа или статистического выражения, возникает вложенность. Уровень вложенности увеличивается каждый раз, когда вызванный модуль или управляемый код начинает выполнение, и уменьшается при завершении его выполнения. Превышение максимальной вложенности (32 уровня) приводит к ошибке выполнения всей цепочки вызовов. Текущий уровень вложенности хранится в системной функции @@NESTLEVEL. Поскольку удаленные хранимые процедуры и расширенные хранимые процедуры не входят в область транзакции (это не относится к транзакциям, начатым инструкцией BEGIN DISTRIBUTED TRANSACTION или при указании различных параметров конфигурации), осуществить откат команд, выполняемых через вызовы к ним, невозможно. Дополнительные сведения см. в разделах Системные хранимые процедуры(Transact-SQL) и BEGIN DISTRIBUTED TRANSACTION (Transact-SQL). Если выполняется процедура, которая передает переменную типа cursor с размещенным в ней курсором, то возникает ошибка. Не надо указывать ключевое слово EXECUTE при выполнении модулей, если эта инструкция стоит первой в пакете. Дополнительные сведения, относящиеся к хранимым процедурам CLR, см. в разделе «Хранимые процедуры CLR». Выполнение хранимых процедур через EXECUTEНе надо указывать ключевое слово EXECUTE при выполнении хранимых процедур, если эта инструкция стоит первой в пакете. Имена системных хранимых процедур SQL Server начинаются с символов «sp_». Физически они хранятся в базе данных Resource, но логически относятся к схеме sys любой системной или определяемой пользователем базе данных. При выполнении системной расширенной хранимой процедуры (в пакете или в модуле, например в пользовательской хранимой процедуре или функции) рекомендуется предварять ее имя указанием схемы sys. Имена системных расширенных хранимых процедур SQL Server начинаются с символов «xp_» и содержатся в схеме dbo базы данных master. При выполнении системной расширенной хранимой процедуры (в пакете или в модуле, например в пользовательской хранимой процедуре или функции) рекомендуется предварять ее имя указанием master.dbo. При выполнении пользовательской хранимой процедуры (в пакете или в модуле, например в пользовательской хранимой процедуре или функции) рекомендуется предварять ее имя указанием схемы. Не рекомендуется давать пользовательским хранимым процедурам те же имена, что и системным. Дополнительные сведения о выполнении хранимых процедур см. в разделе Выполнение хранимых процедур. Указание в EXECUTE символьных строкИзменения в контексте базы данных действуют только до окончания инструкции EXECUTE. Например, после запуска инструкции EXEC контекстом базы данных становится master. Переключение контекстаУказание имени пользователя или имени входаГруппа CompanyDomain\SQLUsers имеет доступ к базе данных Sales. Пользователь CompanyDomain\SqlUser1 является членом группы SQLUsers и, таким образом, неявно имеет доступ к базе данных Sales. Несмотря на то, что пользователь CompanyDomain\SqlUser1 имеет доступ к базе данных как член группы SQLUsers, инструкция EXECUTE @string_variable AS USER = ‘CompanyDomain\SqlUser1’ завершится ошибкой, так как CompanyDomain\SqlUser1 не существует в базе данных в качестве участника. РекомендацииУказывайте имя входа или пользователя, имеющего минимальные права на операции, выполняемые в инструкции или модуле. Например: не следует указывать имя входа, которое обладает разрешениями уровня сервера, если необходимы только разрешения уровня базы данных. Учетную запись владельца базы данных следует указывать только тогда, когда разрешения, которыми он обладает, действительно необходимы. РазрешенияНа выполнение инструкции EXECUTE разрешения не требуются. Однако необходимы разрешения на защищаемые объекты, на которые ссылается командная строка в инструкции EXECUTE. Например, если строка содержит инструкцию INSERT, вызывающий инструкцию EXECUTE пользователь должен иметь разрешение INSERT на целевую таблицу. Разрешения проверяются в месте нахождения инструкции EXECUTE, даже если она содержится внутри модуля. Разрешение EXECUTE на модуль по умолчанию имеет владелец модуля, который может передать его другим пользователям. При запуске модуля, выполняющего командную строку, разрешения проверяются в контексте того пользователя, который выполняет модуль, а не того, который его создал. Но в случае, если владельцем вызывающего и вызываемого модуля является один и тот же пользователь, проверка разрешений EXECUTE для второго модуля не выполняется. Если модуль производит доступ к другому объекту базы данных, то выполнение завершится успешно при наличии разрешения EXECUTE на модуль и при выполнении одного из следующих условий. Модуль помечен как EXECUTE AS USER или SELF, и владелец модуля обладает соответствующими разрешениями на данный объект. Дополнительные сведения об олицетворении в модуле см. в разделе Предложение EXECUTE AS (Transact-SQL). Модуль помечен как EXECUTE AS CALLER, и есть соответствующие разрешения на данный объект. Модуль помечен как EXECUTE AS user_name, а user_name имеет соответствующие разрешения на объект. Разрешения для переключения контекстаЧтобы указать в предложении EXECUTE AS имя входа, вызывающая сторона должна иметь разрешения IMPERSONATE на указанное имя входа. Чтобы указать в предложении EXECUTE AS пользователя базы данных, вызывающая сторона должна иметь разрешения IMPERSONATE на указанное имя входа. Если контекст выполнения не указан или указано EXECUTE AS CALLER, никакие разрешения IMPERSONATE не требуются. Примеры: SQL ServerA. Вызов EXECUTE с передачей единственного аргументаХранимая процедура uspGetEmployeeManagers в базе данных AdventureWorks2012 ожидает один параметр ( @EmployeeID ). В следующем примере производится выполнение хранимой процедуры uspGetEmployeeManagers с Employee ID 6 в качестве значения параметра. При выполнении переменная может быть явно поименована. Если приведенная инструкция является первой в пакете или скрипте osql или sqlcmd, то указывать EXEC не требуется. Б. Передача нескольких аргументовВ. Использование EXECUTE tsql_string с переменнойГ. Использование EXECUTE с удаленной хранимой процедуройОбласть применения: SQL Server 2008 и более поздних версий Д. Использование в инструкции EXECUTE переменной хранимой процедурыВ следующем примере создается переменная, которая содержит имя хранимой процедуры. Е. Указание в инструкции EXECUTE ключевого слова DEFAULTВ следующем примере производится создание хранимой процедуры со значениями по умолчанию для первого и третьего аргументов. При запуске эти значения вставляются в первый и третий аргументы, если они не переданы при вызове процедуры. Обратите внимание, что ключевое слово DEFAULT может использоваться по-разному. Хранимая процедура Proc_Test_Defaults может быть выполнена во множестве разных сочетаний. Ж. Указание AT имя_связанного_сервера в инструкции EXECUTEОбласть применения: SQL Server 2008 и более поздних версий З. Использование инструкции EXECUTE с аргументом WITH RECOMPILEВ следующем примере производится выполнение хранимой процедуры Proc_Test_Defaults с компиляцией нового плана запроса, который после выполнения модуля удаляется. И. Выполнение определяемой пользователем функции с помощью инструкции EXECUTEК. Применение инструкции EXECUTE для запроса к базе данных Oracle на связанном сервереСледующий пример демонстрирует выполнение нескольких инструкций SELECT на удаленном сервере Oracle. Пример начинается с добавления сервера Oracle в качестве связанного и создания имени входа на этом сервере. Область применения: SQL Server 2008 и более поздних версий Л. Переключение контекста на другого пользователя с помощью инструкции EXECUTE AS USERМ. Использование параметра с командами AT имя_связанного_сервера и EXECUTEОбласть применения: SQL Server 2008 и более поздних версий Н. Использование инструкции EXECUTE для переопределения одного результирующего набораПрименимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure О. Использование инструкции EXECUTE для переопределения двух результирующих наборовПри выполнении инструкции, возвращающей более одного результирующего набора, необходимо определить каждый из ожидаемых результирующих наборов. В следующем примере в AdventureWorks2012 создается процедура, которая возвращает два результирующих набора. Затем процедура выполняется с предложением WITH RESULT SETS и указывается два определения результирующих наборов. Применимо к: SQL Server 2012 (11.x) и выше, База данных SQL Azure П. Использование инструкции EXECUTE с data_source_name AT DATA_SOURCE для запроса удаленного SQL ServerВ следующем примере командная строка передается во внешний источник данных, указывающий на экземпляр SQL Server. Область применения: SQL Server 2019 (15.x) и более поздних версий Т. Использование инструкции EXECUTE с data_source_name AT DATA_SOURCE для запроса вычислительного пула в кластере больших данных SQL ServerВ следующем примере командная строка передается во внешний источник данных, указывающий на вычислительный пул в кластере больших данных SQL Server. В примере создается источник данных SqlComputePool для вычислительного пула в кластере больших данных SQL Server и выполняется инструкция SELECT к источнику данных. Область применения: SQL Server 2019 (15.x) и более поздних версий У. Использование инструкции EXECUTE с data_source_name AT DATA_SOURCE для запроса пула данных в кластере больших данных SQL ServerВ следующем примере командная строка передается во внешний источник данных, указывающий на вычислительный пул в кластере больших данных SQL Server. В примере создается источник данных SqlDataPool для пула данных в кластере больших данных SQL Server и выполняется инструкция SELECT к источнику данных. Область применения: SQL Server 2019 (15.x) и более поздних версий Ф. Использование инструкции EXECUTE с data_source_name AT DATA_SOURCE для запроса пула носителей в кластере больших данных SQL ServerВ следующем примере командная строка передается во внешний источник данных, указывающий на вычислительный пул в кластере больших данных SQL Server. В примере создается источник данных SqlStoragePool для пула данных в кластере больших данных SQL Server и выполняется инструкция SELECT к источнику данных. Область применения: SQL Server 2019 (15.x) и более поздних версий Примеры: Azure Synapse AnalyticsA. Выполнение основной процедурыВыполнение хранимой процедуры: Вызов хранимой процедуры с именем, определенным во время выполнения: Вызов хранимой процедуры из хранимой процедуры: Б. Выполнение строкВыполнение строки SQL: Выполнение вложенной строки: Выполнение строковой переменной: В. Процедуры с параметрамиВ следующем примере создается процедура с параметрами и демонстрируется три способа выполнения процедуры. |



