Поделиться через


EXECUTE (Transact-SQL)

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure конечной точке аналитики платформы Аналитики Azure Synapse Analytics (PDW)в Microsoft FabricХранилище в базе данных Microsoft FabricSQL в Microsoft Fabric

Выполняет строку команды или символьную строку в пакете Transact-SQL либо один из следующих модулей: системная хранимая процедура, определяемая пользователем хранимая процедура, хранимая процедура CLR, определяемая пользователем функция со скалярным значением или расширенная хранимая процедура. Инструкцию EXEC или EXECUTE можно использовать для отправки сквозных команд на связанные серверы. или явно указывать контекст, в котором выполняется команда. Метаданные для результирующий набор можно определить с помощью параметров WITH RESULT SETS.

Внимание

Перед вызовом EXECUTE с символьной строкой проверьте строку символов. Никогда не выполняйте команду, созданную из входных данных пользователя, которые не были проверены.

Соглашения о синтаксисе Transact-SQL

Синтаксис

В следующем блоке кода показан синтаксис в SQL Server 2019 (15.x) и более поздних версиях. Также можно посмотреть раздел Синтаксис в SQL Server 2017 и более ранних.

Синтаксис для SQL Server 2019 и более поздних версий.

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS { LOGIN | USER } = ' name ' ]
[ ; ]

-- Execute a pass-through command against a linked server
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'command_string [ ? ]' } [ + ...n ]
        [ { , { value | @variable [ OUTPUT ] } } [ ...n ] ]
    )
    [ AS { LOGIN | USER } = ' name ' ]
    [ AT linked_server_name ]
    [ AT DATA_SOURCE data_source_name ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

В следующем блоке кода показан синтаксис в SQL Server 2017 (14.x) и более ранних версиях. Также можно посмотреть раздел Синтаксис в SQL Server 2019.

Синтаксис для SQL Server 2017 и более ранних версий.

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS { LOGIN | USER } = ' name ' ]
[ ; ]

-- Execute a pass-through command against a linked server
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'command_string [ ? ]' } [ + ...n ]
        [ { , { value | @variable [ OUTPUT ] } } [ ...n ] ]
    )
    [ AS { LOGIN | USER } = ' name ' ]
    [ AT linked_server_name ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

Синтаксис для In-Memory OLTP.

-- Execute a natively compiled, scalar user-defined function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
<execute_option>::=
{
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

Синтаксис базы данных SQL Azure.

-- Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    {
      [ @return_status = ]
      { module_name  | @module_name_var }
        [ [ @parameter = ] { value
                           | @variable [ OUTPUT ]
                           | [ DEFAULT ]
                           }
        ]
      [ ,...n ]
      [ WITH RECOMPILE ]
    }
[ ; ]

-- Execute a character string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS {  USER } = ' name ' ]
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

<result_sets_definition> ::=
{
    (
         { column_name
           data_type
         [ COLLATE collation_name ]
         [ NULL | NOT NULL ] }
         [,...n ]
    )
    | AS OBJECT
        [ db_name . [ schema_name ] . | schema_name . ]
        {table_name | view_name | table_valued_function_name }
    | AS TYPE [ schema_name.]table_type_name
    | AS FOR XML
}

Синтаксис для Azure Synapse Analytics и параллельного хранилища данных.

-- Execute a stored procedure
[ { EXEC | EXECUTE } ]
    procedure_name
        [ { value | @variable [ OUT | OUTPUT ] } ] [ ,...n ]
[ ; ]

-- Execute a SQL string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'tsql_string' } [ +...n ] )
[ ; ]

Синтаксис Для Microsoft Fabric.

-- Execute a stored procedure
[ { EXEC | EXECUTE } ]
    procedure_name
        [ { value | @variable [ OUT | OUTPUT ] } ] [ ,...n ]
        [ WITH <execute_option> [ ,...n ] ]  }
[ ; ]

-- Execute a SQL string
{ EXEC | EXECUTE }
    ( { @string_variable | [ N ] 'tsql_string' } [ +...n ] )
[ ; ]

<execute_option>::=
{
        RECOMPILE
    | { RESULT SETS UNDEFINED }
    | { RESULT SETS NONE }
    | { RESULT SETS ( <result_sets_definition> [,...n ] ) }
}

Аргументы

@return_status

Необязательная целочисленная переменная, которая сохраняет состояние возврата модуля. Эта переменная должна быть объявлена в пакете, хранимой процедуре или функции, прежде чем она будет использоваться в инструкции EXECUTE.

При использовании для вызова скалярной определяемой пользователем функции переменная @return_status может иметь любой скалярный тип данных.

module_name

Полное или неуправляемое имя хранимой процедуры или скалярной определяемой пользователем функции. Имена модулей должны соответствовать правилам для идентификаторов. В именах расширенных хранимых процедур учитывается регистр, вне зависимости от параметров сортировки сервера.

Модуль, созданный в другой базе данных, можно выполнить, если пользователь, на котором запущен модуль, владеет модулем или имеет соответствующее разрешение на его выполнение в этой базе данных. Модуль можно выполнить на другом сервере под управлением SQL Server, если пользователь, на котором запущен модуль, имеет соответствующее разрешение на использование этого сервера (удаленный доступ) и выполнение модуля в этой базе данных. Если имя сервера указано, но имя базы данных не указано, SQL Server ядро СУБД ищет модуль в базе данных по умолчанию пользователя.

number

Необязательное целое число, используемое для группировки процедур с тем же именем. Этот параметр не используется для расширенных хранимых процедур.

Примечание.

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

Дополнительные сведения о группах процедур см. в разделе CREATE PROCEDURE.

@module_name_var

Имя локально определенной переменной, представляющей имя модуля.

Это может быть переменная, содержащая имя скомпилированной в собственном коде скалярной определяемой пользователем функции.

@parameter

Параметр для module_name, как определено в модуле. Имена параметров должны предшествовать знаку (@). При использовании со значением @parameter_name = форме имена параметров и константы не должны быть предоставлены в том порядке, в котором они определены в модуле. Однако если для любого параметра используется значение @parameter_name = , его необходимо использовать для всех последующих параметров.

По умолчанию параметры могут допускать значения NULL.

значение

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

При выполнении транзитных команд для связанных серверов порядок значений параметров зависит от поставщика OLE DB связанного сервера. Большинство поставщиков OLE DB привязывают значения к аргументам слева направо.

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

Если передать одно слово, которое не начинается с @, то оно не заключено в кавычки (например, если вы забыли @ в имени параметра), слово рассматривается как строка nvarchar, несмотря на отсутствующие кавычки.

Если в модуле определено значение по умолчанию, пользователь может вызвать модуль без указания этого параметра.

Значение по умолчанию также может быть NULL. Как правило, определение модуля указывает действие, которое следует предпринять, если значение параметра NULL.

@variable

Переменная, в которой хранится параметр или возвращаемый параметр.

ВЫХОДНЫЕ ДАННЫЕ

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

Если значение определяется как OUTPUT модуля, выполняемого на связанном сервере, все изменения соответствующего @parameter, выполняемые поставщиком OLE DB, копируются обратно в переменную в конце выполнения модуля.

Если используются OUTPUT параметры, и намерение заключается в использовании возвращаемых значений в других инструкциях в вызывающем пакете или модуле, значение параметра должно быть передано в качестве переменной, например @parameter = @variable. Невозможно выполнить модуль, указав OUTPUT для параметра, который не определен как параметр OUTPUT в модуле. Константы нельзя передавать в модуль с помощью OUTPUT; Для возвращаемого параметра требуется имя переменной. Перед выполнением процедуры для переменной должен быть объявлен тип данных и присвоено значение.

Если EXECUTE используется для удаленной хранимой процедуры или для выполнения сквозной команды на связанном сервере, OUTPUT параметры не могут быть одним из типов данных больших объектов (LOB).

Возвращаемые аргументы могут иметь любой тип, кроме типов данных LOB.

ПО УМОЛЧАНИЮ

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

@string_variable

Имя локальной переменной. @string_variable может быть любым char, var char, ncharили типом данных nvarchar nvarchar. В том числе типы данных (max).

[N]'tsql_string'

Константная строка. tsql_string может иметь любой тип данных nvarchar или varchar. Если N включен, строка интерпретируется как тип данных nvarchar.

AS context_specification

Определяет контекст, в котором выполняется инструкция.

ВХОД

Указывает, что воплощаемым контекстом является имя входа, область олицетворения — сервер.

Пользователь

Определяет контекст для олицетворения пользователя в текущей базе данных. Область олицетворения ограничена текущей базой данных. Переключение контекста на пользователя базы данных не наследует разрешения на уровне сервера этого пользователя.

Внимание

При активном переключении контекста на пользователя базы данных любая попытка доступа к ресурсам за пределами базы данных приводит к сбою инструкции. К ним относятся операторы USE <database>, распределенные запросы и запросы, которые ссылаются на другую базу данных с помощью трех частей или четырехкомпонентных идентификаторов.

'name'

Допустимое имя пользователя или имени входа. Аргумент имени должен быть членом предопределенных ролей сервера sysadmin или существовать в качестве участника в sys.database_principals или sys.server_principalsсоответственно.

Этот аргумент не может быть встроенной учетной записью, например NT AUTHORITY\LocalService, NT AUTHORITY\NetworkServiceили NT AUTHORITY\LocalSystem.

Дополнительные сведения см. в разделе Указание имени пользователя или имени входа далее в этой статье.

[N]'command_string'

Константная строка, содержащая команду, передаваемую на связанный сервер. Если N включен, строка интерпретируется как тип данных nvarchar.

[?]

Указывает параметры, для которых указаны значения в <arg-list> команд сквозной передачи, которые используются в инструкции EXECUTE ('...', <arg-list>) AT <linkedsrv>.

AT linked_server_name

Указывает, что command_string выполняется для linked_server_name, а результаты, при их наличии, возвращаются клиенту. Значение linked_server_name должно указывать на существующее определение связанного сервера на локальном сервере. Определение связанного сервера производится при помощи хранимой процедуры sp_addlinkedserver.

  • WITH <execute_option>

    Возможные параметры выполнения. Параметры RESULT SETS нельзя указать в инструкции INSERT...EXECUTE.

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 <execute_option>

    Возможные параметры выполнения. Параметры RESULT SETS нельзя указать в инструкции INSERT...EXECUTE.

    Термин Определение
    RECOMPILE Инициирует перекомпиляцию нового плана, его использование и удаление после выполнения модуля. Если для модуля существует существующий план запроса, этот план остается в кэше.

    Используйте этот параметр, если указанный параметр является нетипичным или если данные значительно изменились. Этот параметр не используется для расширенных хранимых процедур. Мы рекомендуем использовать этот параметр щадя, так как это дорого.

    Примечание. при вызове хранимой процедуры, использующей синтаксис WITH RECOMPILE, нельзя использовать OPENDATASOURCE. Параметр WITH RECOMPILE игнорируется при указании имени объекта четырех частей.

    Примечание.RECOMPILE не поддерживается с скомпилированных в собственном коде скалярных пользовательских функций. Если необходимо выполнить перекомпиляция, используйте sp_recompile.
    RESULT SETS UNDEFINED Этот параметр не гарантирует, какие результаты, если таковые имеются, возвращаются, и определение не предоставляется. Инструкция выполняется без ошибок, независимо от того, возвращаются ли какие-либо результаты. RESULT SETS UNDEFINED — это поведение по умолчанию, если result_sets_option не предоставлен.

    Для интерпретированных скалярных определяемых пользователем функций и собственных скалярных пользовательских функций этот параметр не работает, так как функции никогда не возвращают результирующий набор.

    применяется к: SQL Server 2012 (11.x) и более поздним версиям и базе данных SQL Azure.
    RESULT SETS NONE Гарантирует, что оператор EXECUTE не возвращает результаты. Если возвращены какие-либо результаты, то пакет отменяется.

    Для интерпретированных скалярных определяемых пользователем функций и собственных скалярных пользовательских функций этот параметр не работает, так как функции никогда не возвращают результирующий набор.

    применяется к: SQL Server 2012 (11.x) и более поздним версиям и базе данных SQL Azure.
    <result_sets_definition> Обеспечивает гарантию того, что результат возвращается, как указано в result_sets_definition. Для выражений, которые возвращают множество результирующих наборов, обеспечьте множество разделов result_sets_definition. Заключите каждый раздел result_sets_definition в скобки, разделяя их запятыми. Дополнительные сведения см. в <result_sets_definition> далее в этой статье.

    Этот параметр всегда приводит к ошибке для скомпилированных в собственном коде скалярных определяемых пользователем функций, поскольку функции никогда не возвращают результирующий набор.

    применяется к: SQL Server 2012 (11.x) и более поздним версиям и базе данных SQL Azure.

    <result_sets_definition> описывает результирующие наборы, возвращаемые выполняемыми операторами. Предложения result_sets_definition имеют следующее значение:

    Термин Определение
    { column_name data_type
    [ COLLATE collation_name ]
    [NULL | NOT NULL] }
    См. следующую таблицу.
    db_name Имя базы данных, содержащей функцию таблицы, представления или табличного значения.
    schema_name Имя схемы, владеющей таблицей, представлением или табличной функцией.
    table_name | view_name | table_valued_function_name Указывает, что возвращаемые столбцы являются теми, которые указаны в функции таблицы, представления или табличного значения. Переменные таблицы, временные таблицы и синонимы не поддерживаются в синтаксисе объектов AS.
    AS TYPE [ schema_name. ]table_type_name Указывает, что возвращаемые столбцы указаны в типе таблицы.
    AS FOR XML Указывает, что xml-результаты из инструкции или хранимой процедуры, вызываемой инструкцией EXECUTE, преобразуются в формат, как если бы они были созданы инструкцией SELECT ... FOR XML .... Все форматирование из директив type в исходной инструкции удаляется, и результаты возвращаются так, как будто директива типа не указана. AS FOR XML не преобразует табличные результаты, отличные от XML, из выполняемой инструкции или хранимой процедуры в XML.
    Термин Определение
    column_name Имена всех столбцов. Если число столбцов отличается от результирующего набора, возникнет ошибка и пакет будет отменен. Если имя столбца отличается от результирующего набора, то возвращаемое имя столбца будет установлено в имя из определения.
    data_type Типы данных для каждого из столбцов. Если типы данных различаются, то выполняется неявное преобразование к определенному типу данных. Если преобразование выполнить не удалось, то пакет отменяется
    COLLATE параметры_сортировки Параметры сортировки для каждого из столбцов. Если имеется несоответствие сортировки, выполняется попытка неявного сортировки. Если это сделать не удалось, пакет отменяется.
    NULL | NOT NULL Допустимость значения NULL для каждого из столбцов. Если определенное значение NULL равно NOT NULL, а возвращаемые данные содержат значения NULL, возникает ошибка, и пакет прерван. Если значение не указано, значение по умолчанию соответствует параметрам ANSI_NULL_DFLT_ON и ANSI_NULL_DFLT_OFF.

    Фактический результирующий набор, возвращаемый во время выполнения, может отличаться от результата, определенного с помощью предложения WITH RESULT SETS одним из следующих способов: число результирующих наборов, количество столбцов, имя столбца, значение NULL и тип данных. Если отличается число результирующих наборов, возникнет ошибка, и пакет будет отменен.

Замечания

Параметры можно предоставить с помощью значения или с помощью @parameter_name = значения. Параметр не является частью транзакции; Таким образом, если параметр изменяется в транзакции, которая позже откатывается, значение параметра не возвращается к предыдущему значению. Возвращаемым вызывающему значением всегда является то значение, которое существует на момент выхода из модуля.

Если модуль вызывает другой модуль, выполняет управляемый код модуля среды CLR, определяемого пользователем типа или статистического выражения, возникает вложенность. Уровень вложенности увеличивается при запуске выполнения вызываемого модуля или ссылки на управляемый код и уменьшается при завершении вызываемого модуля или ссылки на управляемый код. Превышение максимальной вложенности (32 уровня) приводит к ошибке выполнения всей цепочки вызовов. Текущий уровень вложения хранится в системной функции @@NESTLEVEL.

Так как удаленные хранимые процедуры и расширенные хранимые процедуры не входят в область действия транзакции (если не выдается в инструкции BEGIN DISTRIBUTED TRANSACTION или при использовании с различными параметрами конфигурации), команды, выполняемые с помощью вызовов, не могут быть откатированы. Дополнительные сведения см. в разделе Системные хранимые процедуры и BEGIN DISTRIBUTED TRANSACTION.

При использовании переменных курсора при выполнении процедуры, которая передается в переменную курсора с курсором, выделенным для него, возникает ошибка.

При выполнении модулей не нужно указывать ключевое слово EXECUTE, если оператор является первым в пакете.

Дополнительные сведения о хранимых процедурах CLR см. в хранимых процедур CLR.

Использование EXECUTE с хранимыми процедурами

При выполнении хранимых процедур при выполнении инструкции в пакете не нужно указывать ключевое слово EXECUTE.

Системные хранимые процедуры SQL Server начинаются с символов sp_. Они физически хранятся в базе данных ресурсов, но логически отображаются в системной схеме каждой системы и определяемой пользователем базы данных. При выполнении системной расширенной хранимой процедуры (в пакете или в модуле, например в пользовательской хранимой процедуре или функции) рекомендуется предварять ее имя указанием схемы sys.

Системные расширенные хранимые процедуры SQL Server начинаются с символов xp_, и они содержатся в схеме dbo базы данных master. При выполнении системной расширенной хранимой процедуры в пакете или в модуле, например определяемой пользователем хранимой процедуре или функции, рекомендуется указать имя хранимой процедуры с master.dbo.

При выполнении пользовательской хранимой процедуры (в пакете или в модуле, например в пользовательской хранимой процедуре или функции) рекомендуется предварять ее имя указанием схемы. Не рекомендуется называть определяемую пользователем хранимую процедуру с тем же именем, что и системная хранимая процедура. Дополнительные сведения о выполнении хранимых процедур см. в разделе Выполнение хранимой процедуры.

Использование EXECUTE со строкой символов

В SQL Server можно указать типы данных varchar(max) и nvarchar(max), которые позволяют использовать символьные строки до 2 гигабайт данных.

Изменения в контексте базы данных продолжаются только до конца инструкции EXECUTE. Например, после запуска EXECUTE в следующей инструкции контекст базы данных master.

USE master;

EXECUTE ('USE AdventureWorks2022; SELECT BusinessEntityID, JobTitle FROM HumanResources.Employee;');

Переключение контекста

Предложение AS { LOGIN | USER } = '<name>' переключает контекст выполнения динамической инструкции. Если переключение контекста указано в виде EXECUTE ('string') AS <context_specification>, его длительность ограничена областью действия запроса, в котором он выполняется.

Указание имени пользователя или имени входа

Имя пользователя или имени входа, указанное в AS { LOGIN | USER } = '<name>', должно существовать в качестве субъекта в sys.database_principals или sys.server_principals соответственно, или инструкция завершается ошибкой. Кроме того, IMPERSONATE разрешения должны быть предоставлены субъекту. Если вызывающий объект не является владельцем базы данных или является членом предопределенной роли сервера sysadmin, субъект должен существовать, даже если пользователь обращается к базе данных или экземпляру SQL Server через членство в группе Windows. Для примера рассмотрим следующие условия.

  • 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 разрешение на модуль, и одно из следующих условий имеет значение true:

  • Модуль помечается EXECUTE AS USER или EXECUTE AS SELF, а владелец модуля имеет соответствующие разрешения на объект, на который ссылается ссылка. Дополнительные сведения об олицетворении в модуле см. в предложении EXECUTE AS.

  • Модуль помечается EXECUTE AS CALLER, и у вас есть соответствующие разрешения на объект.

  • Модуль помечается EXECUTE AS <user_name>и <user_name> имеет соответствующие разрешения для объекта.

Разрешения переключения контекста

Чтобы указать EXECUTE AS для входа, вызывающий объект должен иметь IMPERSONATE разрешения на указанное имя входа. Чтобы указать EXECUTE AS для пользователя базы данных, вызывающий объект должен иметь IMPERSONATE разрешения на указанное имя пользователя. Если контекст выполнения не указан или EXECUTE AS CALLER не указан, IMPERSONATE разрешения не требуются.

Примеры: SQL Server

Примеры кода Transact-SQL в этой статье используют пример базы данных AdventureWorks2022 или AdventureWorksDW2022, которую можно скачать на домашней странице примеров Microsoft SQL Server и проектов сообщества.

А. Использование EXECUTE для передачи одного параметра

Хранимая uspGetEmployeeManagers процедура в базе данных AdventureWorks2022 ожидает один параметр (@EmployeeID). В следующем примере производится выполнение хранимой процедуры uspGetEmployeeManagers с Employee ID 6 в качестве значения параметра.

EXECUTE dbo.uspGetEmployeeManagers 6;
GO

При выполнении переменная может быть явно поименована.

EXECUTE dbo.uspGetEmployeeManagers @EmployeeID = 6;
GO

Если следующая инструкция является первой инструкцией в пакете или скрипте sqlcmd, EXECUTE не требуется.

dbo.uspGetEmployeeManagers 6;
GO

--Or
dbo.uspGetEmployeeManagers @EmployeeID = 6;
GO

B. Использование нескольких параметров

В следующем примере выполняется spGetWhereUsedProductID хранимая процедура в базе данных AdventureWorks2022. Он передает два параметра: первый параметр является идентификатором продукта (819) и вторым параметром @CheckDate является значением datetime.

DECLARE @CheckDate AS DATETIME;
SET @CheckDate = GETDATE();

EXECUTE dbo.uspGetWhereUsedProductID 819, @CheckDate;
GO

В. Использование EXECUTE "tsql_string" с переменной

Следующий пример показывает, как инструкция EXECUTE обрабатывает динамически построенные строки, содержащие переменные. В примере производится создание курсора tables_cursor, в который помещается список всех пользовательских таблиц в базе данных AdventureWorks2022, а затем на основе этого списка перестраиваются индексы всех таблиц.

DECLARE tables_cursor CURSOR
    FOR SELECT s.name, t.name FROM sys.objects AS t
    INNER JOIN sys.schemas AS s ON s.schema_id = t.schema_id
    WHERE t.type = 'U';

OPEN tables_cursor;

DECLARE @schemaname AS sysname;
DECLARE @tablename AS sysname;

FETCH NEXT FROM tables_cursor INTO @schemaname, @tablename;

WHILE (@@FETCH_STATUS <> -1)
    BEGIN
        EXECUTE ('ALTER INDEX ALL ON ' +
            @schemaname + '.' +
            @tablename + ' REBUILD;');
        FETCH NEXT FROM tables_cursor INTO @schemaname, @tablename;
    END

PRINT 'The indexes on all tables have been rebuilt.';

CLOSE tables_cursor;

DEALLOCATE tables_cursor;

D. Использование EXECUTE с удаленной хранимой процедурой

В следующем примере производится выполнение хранимой процедуры uspGetEmployeeManagers на удаленном сервере SQLSERVER1 и сохранение возвращенного состояния выполнения в переменной @retstat.

DECLARE @retstat AS INT;

EXECUTE
    @retstat = SQLSERVER1.AdventureWorks2022.dbo.uspGetEmployeeManagers
    @BusinessEntityID = 6;

Е. Использование EXECUTE с переменной хранимой процедуры

В следующем примере создается переменная, которая содержит имя хранимой процедуры.

DECLARE @proc_name AS VARCHAR (30);
SET @proc_name = 'sys.sp_who';

EXECUTE @proc_name;

F. Использование EXECUTE с DEFAULT

В следующем примере производится создание хранимой процедуры со значениями по умолчанию для первого и третьего аргументов. При запуске эти значения вставляются в первый и третий аргументы, если они не переданы при вызове процедуры. Обратите внимание, что ключевое слово DEFAULT может использоваться по-разному.

IF OBJECT_ID(N'dbo.ProcTestDefaults', N'P') IS NOT NULL
    DROP PROCEDURE dbo.ProcTestDefaults;
GO

-- Create the stored procedure.
CREATE PROCEDURE dbo.ProcTestDefaults (
    @p1 SMALLINT = 42,
    @p2 CHAR (1),
    @p3 VARCHAR (8) = 'CAR'
)
AS
SET NOCOUNT ON;
SELECT @p1, @p2, @p3;
GO

Хранимая процедура Proc_Test_Defaultsможет быть выполнена во множестве разных сочетаний.

-- Specifying a value only for one parameter (@p2).
EXECUTE dbo.ProcTestDefaults @p2 = 'A';

-- Specifying a value for the first two parameters.
EXECUTE dbo.ProcTestDefaults 68, 'B';

-- Specifying a value for all three parameters.
EXECUTE dbo.ProcTestDefaults 68, 'C', 'House';

-- Using the DEFAULT keyword for the first parameter.
EXECUTE dbo.ProcTestDefaults
    @p1 = DEFAULT,
    @p2 = 'D';

-- Specifying the parameters in an order different from the order defined in the procedure.
EXECUTE dbo.ProcTestDefaults DEFAULT,
    @p3 = 'Local',
    @p2 = 'E';

-- Using the DEFAULT keyword for the first and third parameters.
EXECUTE dbo.ProcTestDefaults DEFAULT, 'H', DEFAULT;
EXECUTE dbo.ProcTestDefaults DEFAULT, 'I', @p3 = DEFAULT;

G. Использование EXECUTE с AT linked_server_name

В следующем примере командная строка передается удаленному серверу. Он создает связанный сервер SeattleSales , который указывает на другой экземпляр SQL Server и выполняет инструкцию DDL (CREATE TABLE) для этого связанного сервера.

EXECUTE sp_addlinkedserver 'SeattleSales', 'SQL Server';
GO

EXECUTE ('CREATE TABLE AdventureWorks2022.dbo.SalesTbl
(SalesID INT, SalesName VARCHAR(10)); ') AT SeattleSales;
GO

H. Использование EXECUTE WITH RECOMPILE

В следующем примере производится выполнение хранимой процедуры Proc_Test_Defaults с компиляцией нового плана запроса, который после выполнения модуля удаляется.

EXECUTE dbo.Proc_Test_Defaults @p2 = 'A' WITH RECOMPILE;
GO

I. Использование EXECUTE с определяемой пользователем функцией

В следующем примере выполняется ufnGetSalesOrderStatusText скалярная определяемая пользователем функция в базе данных AdventureWorks2022. Возвращенное значение сохраняется в переменной @returnstatus. Функции передается один входной аргумент @Status, который имеет тип данных tinyint.

DECLARE @returnstatus AS NVARCHAR (15);
SET @returnstatus = NULL;

EXECUTE
    @returnstatus = dbo.ufnGetSalesOrderStatusText
    @Status = 2;

PRINT @returnstatus;
GO

J. Использование EXECUTE для запроса базы данных Oracle на связанном сервере

Следующий пример демонстрирует выполнение нескольких инструкций SELECT на удаленном сервере Oracle. Пример начинается с добавления сервера Oracle в качестве связанного и создания имени входа на этом сервере.

-- Setup the linked server.
EXECUTE sp_addlinkedserver
    @server = 'ORACLE',
    @srvproduct = 'Oracle',
    @provider = 'OraOLEDB.Oracle',
    @datasrc = 'ORACLE10';

EXECUTE sp_addlinkedsrvlogin
    @rmtsrvname = 'ORACLE',
    @useself = 'false',
    @locallogin = NULL,
    @rmtuser = 'scott',
    @rmtpassword = 'tiger';

EXECUTE sp_serveroption 'ORACLE', 'rpc out', true;
GO

-- Execute several statements on the linked Oracle server.
EXECUTE ('SELECT * FROM scott.emp') AT ORACLE;
GO

EXECUTE ('SELECT * FROM scott.emp WHERE MGR = ?', 7902) AT ORACLE;
GO

DECLARE @v AS INT;
SET @v = 7902;

EXECUTE ('SELECT * FROM scott.emp WHERE MGR = ?', @v) AT ORACLE;
GO

K. Использование EXECUTE AS USER для переключения контекста на другого пользователя

Следующий пример выполняет командную строку Transact-SQL, которая создает таблицу и указывает предложение AS USER для переключения контекста выполнения инструкции с вызывающего на пользователя User1. Ядро СУБД проверяет разрешения User1 при запуске инструкции. Пользователь User1 должен присутствовать в базе данных как пользователь и должен иметь разрешения на создание таблиц в схеме Sales; в противном случае инструкция завершается ошибкой.

EXECUTE ('CREATE TABLE Sales.SalesTable (SalesID INT, SalesName VARCHAR(10));')
AS USER = 'User1';
GO

L. Использование параметра с помощью EXECUTE и AT linked_server_name

В следующем примере командная строка передается удаленному серверу со знаком вопроса (?) в качестве заполнителя для параметра. В примере создается связанный сервер SeattleSales , указывающий на другой экземпляр SQL Server и выполняющий инструкцию SELECT для этого связанного сервера. Инструкция SELECT использует знак вопроса в качестве заполнителя для параметра ProductID (952), предоставляемого после инструкции.

-- Setup the linked server.
EXECUTE sp_addlinkedserver 'SeattleSales', 'SQL Server';
GO

-- Execute the SELECT statement.
EXECUTE ('SELECT ProductID, Name
    FROM AdventureWorks2022.Production.Product
    WHERE ProductID = ? ', 952) AT SeattleSales;
GO

M. Использование EXECUTE для переопределить один результирующий набор

применяется к: SQL Server 2012 (11.x) и более поздним версиям и базе данных SQL Azure.

Некоторые из предыдущих примеров были выполнены EXECUTE dbo.uspGetEmployeeManagers 6;, которые возвращали семь столбцов. Следующий пример показывает использование синтаксиса WITH RESULT SET для изменения имени и типов данных возвращаемого результирующего набора.

EXECUTE uspGetEmployeeManagers 16 WITH RESULT SETS
((
    [Reporting Level] INT NOT NULL,
    [ID of Employee] INT NOT NULL,
    [Employee First Name] NVARCHAR (50) NOT NULL,
    [Employee Last Name] NVARCHAR (50) NOT NULL,
    [Employee ID of Manager] NVARCHAR (MAX) NOT NULL,
    [Manager First Name] NVARCHAR (50) NOT NULL,
    [Manager Last Name] NVARCHAR (50) NOT NULL
));

N. Использование EXECUTE для переопределений двух результирующих наборов

применяется к: SQL Server 2012 (11.x) и более поздним версиям и базе данных SQL Azure.

При выполнении инструкции, возвращающей более одного результирующего набора, необходимо определить каждый из ожидаемых результирующих наборов. В следующем примере в AdventureWorks2022 создается процедура, которая возвращает два результирующих набора. Затем процедура выполняется с помощью предложения WITH RESULT SETS и указания двух определений результирующих наборов.

--Create the procedure
CREATE PROCEDURE Production.ProductList
@ProdName NVARCHAR (50)
AS
-- First result set
SELECT
    ProductID,
    Name,
    ListPrice
FROM Production.Product
WHERE Name LIKE @ProdName;
-- Second result set
SELECT Name,
    COUNT(S.ProductID) AS NumberOfOrders
FROM Production.Product AS P
    INNER JOIN Sales.SalesOrderDetail AS S
        ON P.ProductID = S.ProductID
WHERE Name LIKE @ProdName
GROUP BY Name;
GO

-- Execute the procedure
EXECUTE Production.ProductList '%tire%' WITH RESULT SETS
(
    -- first result set definition starts here
    (ProductID INT,
    [Name] NAME,
    ListPrice MONEY)
    -- comma separates result set definitions
    ,
    -- second result set definition starts here
    ([Name] NAME,
    NumberOfOrders INT)
);

O. Использование EXECUTE с AT DATA_SOURCE data_source_name для запроса удаленного SQL Server

применимо к: SQL Server 2019 (15.x) и более поздним версиям.

В следующем примере командная строка передается во внешний источник данных, указывающий на экземпляр SQL Server.

EXECUTE ( 'SELECT @@SERVERNAME' ) AT DATA_SOURCE my_sql_server;
GO

P. Использование EXECUTE с AT DATA_SOURCE data_source_name для запроса пула вычислений в кластере больших данных SQL Server

применимо к: SQL Server 2019 (15.x).

В следующем примере командная строка передается во внешний источник данных, указывающий на вычислительный пул в кластере больших данных SQL Server. В примере создается источник данных SqlComputePool для вычислительного пула в кластере больших данных SQL Server и выполняется инструкция SELECT к источнику данных.

CREATE EXTERNAL DATA SOURCE SqlComputePool
WITH (LOCATION = 'sqlcomputepool://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlComputePool;
GO

В. Использование EXECUTE с AT DATA_SOURCE data_source_name для запроса пула данных в кластере больших данных SQL Server

применимо к: SQL Server 2019 (15.x).

В следующем примере выполняется передача командной строки во внешний источник данных, указывающий на пул вычислений в кластере больших данных SQL Server (BDC). В этом примере создается SqlDataPool источника данных для пула данных в BDC и выполняется инструкция SELECT для источника данных.

CREATE EXTERNAL DATA SOURCE SqlDataPool
WITH (LOCATION = 'sqldatapool://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlDataPool;
GO

R. Использование EXECUTE с AT DATA_SOURCE data_source_name для запроса пула носителей в кластере больших данных SQL Server

применимо к: SQL Server 2019 (15.x).

В следующем примере командная строка передается во внешний источник данных, указывающий на вычислительный пул в кластере больших данных SQL Server. В примере создается источник данных SqlStoragePool для пула данных в кластере больших данных SQL Server и выполняется инструкция SELECT к источнику данных.

CREATE EXTERNAL DATA SOURCE SqlStoragePool
WITH (LOCATION = 'sqlhdfs://controller-svc/default');

EXECUTE ('SELECT @@SERVERNAME') AT DATA_SOURCE SqlStoragePool;
GO

Примеры: Azure Synapse Analytics

Примеры кода Transact-SQL в этой статье используют пример базы данных AdventureWorks2022 или AdventureWorksDW2022, которую можно скачать на домашней странице примеров Microsoft SQL Server и проектов сообщества.

Ответ. Базовое выполнение процедуры

Выполните хранимую процедуру:

EXECUTE proc1;

Вызов хранимой процедуры с именем, определенным во время выполнения:

EXECUTE ('EXECUTE ' + @var);

Вызов хранимой процедуры из хранимой процедуры:

CREATE sp_first AS EXECUTE sp_second; EXECUTE sp_third;

B. Выполнение строк

Выполните строку SQL:

EXECUTE ('SELECT * FROM sys.types');

Выполните вложенную строку:

EXECUTE ('EXECUTE (''SELECT * FROM sys.types'')');

Выполните строковую переменную:

DECLARE @stringVar AS NVARCHAR (100);
SET @stringVar = N'SELECT name FROM' + ' sys.sql_logins';

EXECUTE (@stringVar);

C. Процедуры с параметрами

В следующем примере создается процедура с параметрами и демонстрируется три способа выполнения процедуры:

CREATE PROCEDURE ProcWithParameters (
    @name NVARCHAR (50),
    @color NVARCHAR (15)
)
AS
SELECT ProductKey,
       EnglishProductName,
       Color
FROM [dbo].[DimProduct]
WHERE EnglishProductName LIKE @namef
      AND Color = @color;
GO

Выполнение с помощью позиционных параметров:

EXECUTE ProcWithParameters N'%arm%', N'Black';

Выполните выполнение с помощью именованных параметров в порядке:

EXECUTE ProcWithParameters
    @name = N'%arm%',
    @color = N'Black';

Выполните выполнение с помощью именованных параметров вне порядка:

EXECUTE ProcWithParameters
    @color = N'Black',
    @name = N'%arm%';
GO