適用対象:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Microsoft Fabric の SQL 分析エンドポイント
Microsoft Fabric のウェアハウス
Microsoft Fabric の SQL データベース
Transact-SQL 文の列を論理コードブロックに囲み込む。 この BEGIN の使い方は、 BEGIN TRANSACTION 文や BEGIN ATOMIC 文とは無関係です。
BEGIN...ENDブロックを、IF、ELSE、WHILEなどの前置のフロー制御文と組み合わせて使用できます。 しかし、これらのブロックを先行のフローコントロール文なしで使えば、文の列を組織的にグループ化することも可能です。 しかし、新しい BEGIN...END ブロックごとに新しい語彙範囲が生まれるわけではありません。
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 TRANSACTIONやBEGIN ATOMICの文との混乱を避けるために、BEGIN後にセミコロンを付けてください。ENDの後にセミコロンを使うことで、特にWITHキーワードやTHROW文の後続の文にセミコロンが不要になります。
すべての Transact-SQL 文は BEGIN...END ブロック内で有効ですが、特定の Transact-SQL 文を同じバッチや文ブロック内でまとめてはいけません。 文が既存の Transact-SQL バッチ要件と矛盾しないようにしてください。
Examples
この記事のコード サンプルでは、AdventureWorks2025 または AdventureWorksDW2025 サンプル データベースを使用します。このサンプル データベースは、Microsoft SQL Server サンプルとコミュニティ プロジェクト ホーム ページからダウンロードできます。
A。 論理関連文の列を順序ごとに定義します
以下の例では、 BEGIN と END が論理関連の 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
次の例では、BEGIN と END を使用して、まとめて実行する一連の 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. 一連の文を定義し、それらが一緒に動く
次の例では、BEGIN と END を使用して、まとめて実行する一連の SQL ステートメントを定義します。
注意事項
BEGINとENDキーワードを取り除くと、次の例は無限ループで動作します。
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