次の方法で共有


始める。。。終わり(Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric の SQL 分析エンドポイントMicrosoft Fabric のウェアハウスMicrosoft Fabric の SQL データベース

Transact-SQL 文の列を論理コードブロックに囲み込む。 この BEGIN の使い方は、 BEGIN TRANSACTION 文や BEGIN ATOMIC 文とは無関係です。

BEGIN...ENDブロックを、IFELSEWHILEなどの前置のフロー制御文と組み合わせて使用できます。 しかし、これらのブロックを先行のフローコントロール文なしで使えば、文の列を組織的にグループ化することも可能です。 しかし、新しい BEGIN...END ブロックごとに新しい語彙範囲が生まれるわけではありません。

Transact-SQL 構文表記規則

Syntax

BEGIN [ ; ]
    { sql_statement | statement_block }
END [ ; ]

Arguments

{ sql_statement | statement_block}

ステートメント ブロックを使用して定義された、有効な Transact-SQL ステートメントまたはステートメント グループ化。

Remarks

BEGIN...ENDブロックには少なくとも1つの文が含まれていなければなりません。 空の BEGIN...END ブロックを使おうとすると、各キーワードの後にセミコロンを使っていても構文エラーが発生します。 GOTOラベルをプレースホルダー文として使うことで、空のブロックBEGIN...ENDを避けられます。 例C参照:動的に生成されるBEGIN...にはGOTOラベルを使う。エンドブロック。

BEGIN...END ブロックは入れ子にすることができます。

BEGIN...END ブロックは語彙の範囲を定義しません。 ブロック内で変数を宣言すると、それは DECLARE 文を含むブロック内だけでなく、親バッチ全体で見えます。

複数のバッチで BEGIN...END ブロックを使うことはできません。 例えば、BEGIN...ENDブロック内でGOバッチセパレーターを使うことはできません。

BEGIN...ENDブロックを使って文をグループ化しても、グループ内のすべての文が原子的に実行されるわけではありません。 トランザクションの外でバッチが実行され、エラーが発生したり、マルチステートメント BEGIN...END ブロックの2番目の文で例外が出された場合、最初の文はロールバックされません。

BEGINおよびENDキーワードの後のセミコロンは任意ですが、以下のような場合を除き推奨されます。

  • 共通のテーブル式(CTE)を始めるWITHキーワードの前にセミコロンが必要です。

  • ブロック内にセミコロンと THROW 文が必要です。

  • BEGIN TRANSACTIONBEGIN ATOMICの文との混乱を避けるために、BEGIN後にセミコロンを付けてください。

  • ENDの後にセミコロンを使うことで、特にWITHキーワードやTHROW文の後続の文にセミコロンが不要になります。

すべての Transact-SQL 文は BEGIN...END ブロック内で有効ですが、特定の Transact-SQL 文を同じバッチや文ブロック内でまとめてはいけません。 文が既存の Transact-SQL バッチ要件と矛盾しないようにしてください。

Examples

この記事のコード サンプルでは、AdventureWorks2025 または AdventureWorksDW2025 サンプル データベースを使用します。このサンプル データベースは、Microsoft SQL Server サンプルとコミュニティ プロジェクト ホーム ページからダウンロードできます。

以下の例では、 BEGINEND が論理関連の Transact-SQL 文の列を順序通りに実行することを定義します。 例では入れ子されたブロックも示されています。

USE AdventureWorks2025;
GO

DECLARE @personId AS INT = (
    SELECT p.BusinessEntityID
    FROM Person.Person AS p
    WHERE p.rowguid = { GUID '92C4279F-1207-48A3-8448-4636514EB7E2' }
);

IF (@personId IS NULL)
    THROW 50001, 'Person not found.', 1;

/* Concatenate the person's name fields: */;
BEGIN
    DECLARE @title AS NVARCHAR (8),
            @first AS NVARCHAR (50),
            @middle AS NVARCHAR (50),
            @last AS NVARCHAR (50),
            @suffix AS NVARCHAR (10);

    SELECT @title = NULLIF (p.Title, N''),
           @first = p.FirstName,
           @middle = NULLIF (p.MiddleName, N''),
           @last = p.LastName,
           @suffix = NULLIF (p.Suffix, N'')
    FROM Person.Person AS p
    WHERE p.BusinessEntityID = @personId;

    DECLARE @nameConcat AS NVARCHAR (255) = CONCAT_WS(N' ', @title, @first, @middle, @last, @suffix);

    /* This is a nested BEGIN...END block: */;
    BEGIN
        DECLARE @emails AS NVARCHAR (MAX) = (
            SELECT STRING_AGG(e.EmailAddress, /*separator:*/N'; ')
            FROM Person.EmailAddress AS e
            WHERE e.BusinessEntityID = @personId
        );

        SET @nameConcat = CONCAT(@nameConcat, N' (', @emails, N')');
    END
END

/* BEGIN...END blocks do not define a lexical scope, so
   even though @nameAndEmails is declared above, it is
   still in-scope after the END keyword. */
SELECT @nameConcat AS NameAndEmails;

B: Use BEGIN...トランザクションにおけるEN

次の例では、BEGINEND を使用して、まとめて実行する一連の Transact-SQL ステートメントを定義します。 BEGIN...ENDブロックが含まれていない場合、両方のROLLBACK TRANSACTION文が実行され、両方のPRINTメッセージが返されます。

USE AdventureWorks2025;
GO

BEGIN TRANSACTION;

IF @@TRANCOUNT = 0
    BEGIN
        SELECT FirstName,
               MiddleName
        FROM Person.Person
        WHERE LastName = 'Adams';

        ROLLBACK TRANSACTION;

        PRINT N'Rolling back the transaction two times causes an error.';
    END

ROLLBACK TRANSACTION;

PRINT N'Rolled back the transaction.';

C. 動的に生成されるBEGIN...にはGOTOラベルを使います。エンドブロック

BEGIN...ENDブロックで動的 Transact-SQL を生成し、プログラムで常にBEGIN...ENDキーワードをレンダリングしたい場合、GOTOラベルをプレースホルダー文として使って、BEGIN...ENDブロックが空になるのを避けられます。

BEGIN
    unusedLabel:
END

例: Azure Synapse Analytics、Analytics Platform System (PDW)

C. 一連の文を定義し、それらが一緒に動く

次の例では、BEGINEND を使用して、まとめて実行する一連の SQL ステートメントを定義します。

注意事項

BEGINENDキーワードを取り除くと、次の例は無限ループで動作します。 WHILE文はSELECTクエリのみをループし、SET @Iteration += 1文には到達しません。

-- Uses AdventureWorksDW;
DECLARE @Iteration AS INT = 0;

WHILE @Iteration < 10
    BEGIN
        SELECT FirstName,
               MiddleName
        FROM dbo.DimCustomer
        WHERE LastName = 'Adams';
        SET @Iteration + = 1;
    END