次の方法で共有


EXECUTE (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric の SQL 分析エンドポイントMicrosoft Fabric WarehouseMicrosoft Fabric SQL Database

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 ] ) }
}

Azure SQL Database の構文。

-- 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 と Parallel Data Warehouse の構文。

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

同じ名前のプロシージャをグループ化するために使用される省略可能な整数。 このパラメーターは、拡張ストアド プロシージャには使用されません。

Note

この機能は、 SQL Serverの将来のバージョンで削除される予定です。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。

プロシージャー・グループの詳細については、「CREATE PROCEDURE参照してください。

@module_name_var

モジュール名を表すローカル定義変数の名前。

ネイティブ コンパイル、スカラー ユーザー定義関数の名前を保持する変数を指定できます。

@parameter

モジュールで定義されている module_nameのパラメーター。 パラメーター名の前にアット マーク (@) を付ける必要があります。 @parameter_name = フォームで使用する場合、パラメーター名と定数は、モジュールで定義されている順序で指定する必要はありません。 ただし、@parameter_name = フォームを任意のパラメーターに使用する場合は、後続のすべてのパラメーターに使用する必要があります。

既定では、パラメーターに NULL 値は許容されます。

value

モジュールまたはパススルー コマンドに渡すパラメーターの値。 パラメーター名を指定しない場合は、モジュールで定義されている順序でパラメーター値を指定する必要があります。

リンク サーバーに対してパススルー コマンドを実行するとき、パラメーター値の順序は、リンク サーバーの OLE DB プロバイダーに依存します。 ほとんどの OLE DB プロバイダーでは、左から右へパラメーターに値がバインドされます。

パラメーターの値がオブジェクト名や文字列であったり、データベース名やスキーマ名によって修飾されている場合は、その名前全体を単一引用符で囲む必要があります。 パラメーターの値がキーワードの場合は、そのキーワードを二重引用符で囲む必要があります。

引用符で囲まれていない @で始まらない 1 つの単語を渡した場合 (たとえば、パラメーター名に @ を忘れた場合)、単語は引用符が見つからないにもかかわらず、nvarchar 文字列として扱われます。

既定値がモジュール内で定義されている場合、ユーザーはパラメーターを指定せずにモジュールを実行できます。

既定値は NULLすることもできます。 一般に、モジュール定義は、パラメーター値が NULL場合に実行する必要があるアクションを指定します。

@variable

パラメーターまたは戻り値パラメーターを格納する変数。

OUTPUT

モジュールまたはコマンド文字列でパラメーターを返すよう指定します。 モジュールまたはコマンド文字列内の一致するパラメーターも、キーワード OUTPUTを使用して作成されている必要があります。 このキーワードは、カーソル変数をパラメーターとして使用するときに指定します。

リンク サーバーに対して実行されるモジュールの OUTPUT として定義されている場合、OLE DB プロバイダーによって実行される対応する @parameter に対する変更は、モジュールの実行の最後に変数にコピーされます。

OUTPUT パラメーターが使用されていて、呼び出し元のバッチまたはモジュール内の他のステートメントで戻り値を使用することを意図している場合は、パラメーターの値を変数 (@parameter = @variableなど) として渡す必要があります。 モジュールで OUTPUT パラメーターとして定義されていないパラメーターの OUTPUT を指定して、モジュールを実行することはできません。 定数は、OUTPUTを使用してモジュールに渡すことはできません。戻り値のパラメーターには変数名が必要です。 プロシージャを実行する前に、必ず変数のデータ型を宣言し、値を割り当ててください。

リモート ストアド プロシージャに対して EXECUTE を使用する場合、またはリンク サーバーに対してパススルー コマンドを実行する場合、OUTPUT パラメーターをラージ オブジェクト (LOB) データ型にすることはできません。

戻りパラメーターには、LOB 型以外のデータ型を指定できます。

DEFAULT

モジュールで定義されているパラメーターの既定値を使用します。 モジュールが、定義された既定値を持たないパラメーターの値を予期していて、パラメーターが見つからないか、DEFAULT キーワードが指定されている場合、エラーが発生します。

@string_variable

ローカル変数の名前。 @string_variable は、任意の 文字varcharnchar、または nvarchar データ型 できます。 これには、 (max) データ型が含まれます。

[N]'tsql_string'

定数文字列。 tsql_string には、nvarchar または varchar のいずれかのデータ型を指定できます。 が含まれている場合、文字列は nvarchar データ型 解釈されます。

AS context_specification

ステートメントを実行するコンテキストを指定します。

Login

権限を借用するコンテキストがログインであることを指定します。 権限借用のスコープはサーバーです。

User

権限を借用するコンテキストが、現在のデータベース内のユーザーであることを指定します。 権限借用のスコープは、現在のデータベースに限定されます。 データベース ユーザーへのコンテキスト切り替えでは、そのユーザーのサーバー レベルのアクセス許可は継承されません。

重要

データベース ユーザーへのコンテキスト切り替えがアクティブになっている間に、データベースの外部のリソースにアクセスしようとすると、ステートメントが失敗します。 これには、USE <database> ステートメント、分散クエリ、3 部構成または 4 部構成の識別子を使用して別のデータベースを参照するクエリが含まれます。

'name'

有効なユーザーまたはログイン名。 引数は、固定サーバー ロール sysadmin のメンバーであるか、sys.database_principals または sys.server_principalsのプリンシパルとして存在する必要があります。

この引数は、NT AUTHORITY\LocalServiceNT AUTHORITY\NetworkServiceNT AUTHORITY\LocalSystemなどの組み込みアカウントにすることはできません。

詳細については、この記事で後述する「ユーザー名またはログイン名 の指定」を参照してください。

[N]'command_string'

リンク サーバーに渡されるコマンドを含む定数文字列。 が含まれている場合、文字列は nvarchar データ型 解釈されます。

[?]

<arg-list> ステートメントで使用されるパススルー コマンドの EXECUTE ('...', <arg-list>) AT <linkedsrv> で値を指定するパラメーターを示します。

AT linked_server_name

command_stringlinked_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_stringdata_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 オプションは、4 部構成のオブジェクト名が指定されている場合は無視されます。

    注:RECOMPILE は、ネイティブ コンパイルのスカラー ユーザー定義関数ではサポートされていません。 再コンパイルする必要がある場合は、sp_recompileを使用します。
    RESULT SETS UNDEFINED このオプションでは、返される結果の保証はなく、定義も指定されません。 ステートメントは、何かの結果が返される場合でも、結果が返されない場合でも、問題なく実行されます。 RESULT SETS UNDEFINED は、result_sets_optionが指定されていない場合の既定の動作です。

    解釈されたスカラー ユーザー定義関数とネイティブ コンパイル スカラー ユーザー定義関数の場合、関数は結果セットを返さないため、このオプションは動作しません。

    : SQL Server 2012 (11.x) 以降のバージョン、および Azure SQL Database に適用されます。
    RESULT SETS NONE EXECUTE ステートメントが結果を返さないことを保証します。 結果が返された場合、バッチは中断されます。

    解釈されたスカラー ユーザー定義関数とネイティブ コンパイル スカラー ユーザー定義関数の場合、関数は結果セットを返さないため、このオプションは動作しません。

    : SQL Server 2012 (11.x) 以降のバージョン、および Azure SQL Database に適用されます。
    <result_sets_definition> result_sets_definitionで指定された結果が返されることを保証します。 複数の結果セットを返すステートメントの場合は、複数の result_sets_definition セクションを指定してください。 その際には、各 result_sets_definition をかっこで囲み、コンマで区切ります。 詳細については、この記事の後半の <result_sets_definition> を参照してください。

    ネイティブ コンパイルのスカラー ユーザー定義関数の場合、関数が結果セットを返すことがないため、このオプションの結果は常にエラーになります。

    : SQL Server 2012 (11.x) 以降のバージョン、および Azure SQL Database に適用されます。

    <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 EXECUTE ステートメントによって呼び出されたステートメントまたはストアド プロシージャの XML 結果が、SELECT ... FOR XML ... ステートメントによって生成された形式に変換されるように指定します。 元のステートメントの型ディレクティブからのすべての書式設定が削除され、返される結果は型ディレクティブが指定されていないかのように表示されます。 AS FOR XML では、XML 以外の表形式の結果は、実行されたステートメントまたはストアド プロシージャから XML に変換されません。
    期間 定義
    column_name 各列の名前です。 列の数が結果セットと異なる場合は、エラーが発生し、バッチが中断されます。 列の名前が結果セットと異なる場合は、返される列の名前は定義済みの名前に設定されます。
    data_type 各列のデータ型です。 データ型が異なる場合は、定義済みのデータ型への暗黙的な変換が行われます。 変換に失敗すると、バッチが中断されます。
    COLLATE collation_name 各列の照合順序です。 照合順序が一致しない場合は、暗黙的な照合順序が試行されます。 これに失敗した場合は、バッチが中断されます。
    NULL | NOT NULL 各列の NULL 値の許容属性です。 定義された null 許容が NOT NULL され、返されたデータに null が含まれている場合、エラーが発生し、バッチが中止されます。 指定しない場合、既定値は ANSI_NULL_DFLT_ON オプションと ANSI_NULL_DFLT_OFF オプションの設定に準拠します。

    実行中に返される実際の結果セットは、結果セットの数、列の数、列名、null 許容、データ型のいずれかの方法で、WITH RESULT SETS 句を使用して定義された結果とは異なる場合があります。 結果セットの数が異なる場合は、エラーが発生し、バッチが中断されます。

解説

パラメーターは、 を使用するか、@parameter_name = を使用して指定できます。 パラメーターはトランザクションの一部ではありません。そのため、後でロールバックされるトランザクションでパラメーターが変更された場合、パラメーターの値は以前の値に戻りません。 呼び出し元に返される値は常に、モジュールから戻る時点での値になります。

1 つのモジュールで、別のモジュールが呼び出されるか、共通言語ランタイム (CLR) モジュール、ユーザー定義型、または集計の参照によりマネージド コードが実行されるとき、入れ子が発生します。 入れ子レベルは、呼び出されたモジュールまたはマネージド コード参照が実行を開始するとインクリメントされ、呼び出されたモジュールまたはマネージド コード参照が完了するとデクリメントされます。 入れ子のレベルが最大値 32 を超えると、呼び出しチェーン全体が失敗します。 現在の入れ子レベルは、@@NESTLEVEL システム関数に格納されます。

リモート ストアド プロシージャと拡張ストアド プロシージャはトランザクションのスコープ内にないため (BEGIN DISTRIBUTED TRANSACTION ステートメント内で発行された場合や、さまざまな構成オプションで使用されている場合を除く)、それらの呼び出しを通じて実行されるコマンドはロールバックできません。 詳細については、「システム ストアド プロシージャ および BEGIN DISTRIBUTED TRANSACTIONする」を参照してください。

カーソル変数を使用する場合、カーソル変数にカーソルを割り当てて渡すプロシージャを実行すると、エラーが発生します。

ステートメントがバッチの最初のステートメントである場合は、モジュールの実行時に EXECUTE キーワードを指定する必要はありません。

CLR ストアド プロシージャに固有の詳細については、「CLR ストアド プロシージャの」を参照してください。

ストアド プロシージャで EXECUTE を使用する

ステートメントがバッチの最初のステートメントである場合にストアド プロシージャを実行するときに、EXECUTE キーワードを指定する必要はありません。

SQL Server システム ストアド プロシージャは、sp_文字で始まります。 これらは物理的に リソース データベースに格納されますが、論理的には、すべてのシステムおよびユーザー定義データベースの sys スキーマに表示されます。 システム ストアド プロシージャを、バッチ内、またはユーザー定義ストアド プロシージャや関数などのモジュール内で実行する場合は、ストアド プロシージャ名に sys スキーマ名を追加することをお勧めします。

SQL Server システム拡張ストアド プロシージャは、xp_文字で始まり、master データベースの dbo スキーマに含まれています。 システム拡張ストアド プロシージャをバッチで実行する場合、またはユーザー定義ストアド プロシージャや関数などのモジュール内で実行する場合は、ストアド プロシージャ名を master.dboで修飾することをお勧めします。

ユーザー定義ストアド プロシージャを、バッチ内、またはユーザー定義ストアド プロシージャや関数などのモジュール内で実行する場合は、ストアド プロシージャ名にスキーマ名を追加することをお勧めします。 システム ストアド プロシージャと同じ名前のユーザー定義ストアド プロシージャに名前を付けることはできません。 ストアド プロシージャの実行の詳細については、「ストアド プロシージャの実行を参照してください。

文字列で EXECUTE を使用する

SQL Server では、varchar(max) 型と nvarchar(max) 型を指定でき、2 GB までの文字列データを使用できるようになりました。

データベース コンテキストの変更は、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 のメンバーでない限り、ユーザーが Windows グループ メンバーシップを介して SQL Server のデータベースまたはインスタンスにアクセスしている場合でも、プリンシパルが存在する必要があります。 たとえば、次のような条件を想定します。

  • CompanyDomain\SQLUsers グループは、Sales データベースにアクセスできます。

  • CompanyDomain\SqlUser1SQLUsers のメンバーであるため、Sales データベースに暗黙的にアクセスできます。

CompanyDomain\SqlUser1 は、SQLUsers グループのメンバーシップを介してデータベースにアクセスできますが、EXECUTE @string_variable AS USER = 'CompanyDomain\SqlUser1' がデータベースのプリンシパルとして存在しないため、ステートメント CompanyDomain\SqlUser1 は失敗します。

ベスト プラクティス

ステートメントまたはモジュールで定義されている操作の実行に必要な、最小の権限が与えられているログインまたはユーザーを指定します。 たとえば、データベース レベルのアクセス許可のみが必要な場合は、サーバー レベルのアクセス許可を持つログイン名を指定しないでください。 または、これらのアクセス許可が必要な場合を除き、データベース所有者アカウントを指定しないでください。

アクセス許可

EXECUTE ステートメントを実行するためにアクセス許可は必要ありません。 ただし、EXECUTE 文字列内で参照されるセキュリティ保護可能なリソースに対するアクセス許可が必要です。 たとえば、文字列に INSERT ステートメントが含まれている場合、EXECUTE ステートメントの呼び出し元には、ターゲット テーブルに対する INSERT アクセス許可が必要です。 EXECUTE ステートメントがモジュール内に含まれている場合でも、EXECUTE ステートメントが検出された時点でアクセス許可がチェックされます。

EXECUTE モジュールのアクセス許可は、既定でモジュールの所有者に割り当て、他のユーザーに転送できます。 文字列を実行するモジュールが実行されるとき、権限は、モジュールを作成したユーザーのコンテキストではなく、モジュールを実行しているユーザーのコンテキストに基づいて確認されます。 ただし、同じユーザーが呼び出し元のモジュールと呼び出されているモジュールを所有している場合、EXECUTE アクセス許可チェックは 2 番目のモジュールに対して実行されません。

モジュールが他のデータベース オブジェクトにアクセスする場合、モジュールに対する EXECUTE 権限があり、次のいずれかの条件が当てはまる場合、実行は成功します。

  • モジュールは 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 サンプルとコミュニティ プロジェクト ホーム ページからダウンロードできます。

A. EXECUTE を使用して 1 つのパラメーターを渡す

AdventureWorks2022 データベースの uspGetEmployeeManagers ストアド プロシージャでは、1 つのパラメーター (@EmployeeID) を指定する必要があります。 次の例では、uspGetEmployeeManagers をパラメーター値として使用し、Employee ID 6 ストアド プロシージャを実行します。

EXECUTE dbo.uspGetEmployeeManagers 6;
GO

実行の中で明示的に変数を指定することもできます。

EXECUTE dbo.uspGetEmployeeManagers @EmployeeID = 6;
GO

バッチ内の最初のステートメントまたは sqlcmd スクリプト 次の場合、 は必要ありません。

dbo.uspGetEmployeeManagers 6;
GO

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

B. 複数のパラメーターを使用する

次の例では、AdventureWorks2022 データベースで spGetWhereUsedProductID ストアド プロシージャを実行します。 2 つのパラメーターが渡されます。最初のパラメーターは製品 ID (819) で、2 番目のパラメーター @CheckDatedatetime 値です。

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

EXECUTE dbo.uspGetWhereUsedProductID 819, @CheckDate;
GO

C. 変数で 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 を使用する

次の例では、リモート サーバー uspGetEmployeeManagersSQLSERVER1 ストアド プロシージャを実行し、@retstat に成功または失敗を示す戻りステータスを格納します。

DECLARE @retstat AS INT;

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

E. ストアド プロシージャ変数で EXECUTE を使用する

次の例では、ストアド プロシージャ名を表す変数を作成します。

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

EXECUTE @proc_name;

F. EXECUTE と DEFAULT を使用する

次の例では、第 1 および第 3 パラメーターに既定値を指定して、ストアド プロシージャを作成します。 プロシージャを実行するとき、値を指定しなかったり、既定値が指定されていた場合は、これらの既定値が第 1 および第 3 パラメーターに挿入されます。 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. AT linked_server_name で EXECUTE を使用する

次の例では、コマンド文字列をリモート サーバーに渡します。 ここでは、SQL Server の別のインスタンスをポイントするリンク サーバー SeattleSales を作成し、そのリンク サーバーに対して 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 を使用する

次の例では、AdventureWorks2022 データベースでユーザー定義のスカラー関数 ufnGetSalesOrderStatusText を実行します。 ここでは、変数 @returnstatus を使用して、関数によって返される値を格納します。 この関数には 1 つの入力パラメーター @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 でパラメーターを使用する

次の例では、パラメーターのプレースホルダーとして疑問符 (?) を使用し、コマンド文字列をリモート サーバーに渡します。 ここでは、SQL Server の別のインスタンスをポイントするリンク サーバー SeattleSales を作成し、そのリンク サーバーに対して 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 を使用して 1 つの結果セットを再定義する

: SQL Server 2012 (11.x) 以降のバージョン、および Azure SQL Database に適用されます。

前の例の一部は、7 つの列を返 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
));

北 EXECUTE を使用して 2 つの結果セットを再定義する

: SQL Server 2012 (11.x) 以降のバージョン、および Azure SQL Database に適用されます。

複数の結果セットを返すステートメントを実行する場合は、予期される各結果セットを定義してください。 AdventureWorks2022 の次の例では、2 つの結果セットを返すプロシージャを作成します。 その後、プロシージャは WITH RESULT SETS 句を使用し、2 つの結果セット定義を指定して実行されます。

--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. AT DATA_SOURCE data_source_name で EXECUTE を使用してリモート SQL Server にクエリを実行する

: SQL Server 2019 (15.x) 以降のバージョンに適用されます。

次の例では、SQL Server インスタンスをポイントする外部データ ソースにコマンド文字列を渡します。

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

P. AT DATA_SOURCE data_source_name で EXECUTE を使用して SQL Server ビッグ データ クラスターのコンピューティング プールにクエリを実行する

: SQL Server 2019 (15.x) に適用されます。

次の例では、SQL Server ビッグ データ クラスターのコンピューティング プールをポイントする外部データ ソースにコマンド文字列を渡します。 この例では SQL Server ビッグ データ クラスターのコンピューティング プールに対してデータ ソース SqlComputePool を作成し、そのデータ ソースに対して SELECT ステートメントを実行します。

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

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

Q. AT DATA_SOURCE data_source_name で EXECUTE を使用して SQL Server ビッグ データ クラスターのデータ プールにクエリを実行する

: SQL Server 2019 (15.x) に適用されます。

次の例では、SQL Server ビッグ データ クラスター (BDC) のコンピューティング プールを指す外部データ ソースにコマンド文字列を渡します。 この例では、BDC のデータ プールに対してデータ ソース SqlDataPool を作成し、データ ソースに対して SELECT ステートメントを実行します。

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

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

R. AT DATA_SOURCE data_source_name で EXECUTE を使用して SQL Server ビッグ データ クラスターの記憶域プールにクエリを実行する

: SQL Server 2019 (15.x) に適用されます。

次の例では、SQL Server ビッグ データ クラスターのコンピューティング プールをポイントする外部データ ソースにコマンド文字列を渡します。 この例では SQL Server ビッグ データ クラスターのデータ プールに対してデータ ソース SqlStoragePool を作成し、そのデータ ソースに対して 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 サンプルとコミュニティ プロジェクト ホーム ページからダウンロードできます。

A: 基本的なプロシージャの実行

ストアド プロシージャを実行します。

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: パラメーターを持つプロシージャ

次の例では、パラメーターを持つプロシージャを作成し、プロシージャを実行する 3 つの方法を示します。

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