SQLのBEGINについてまとめています。
BEGINには、ストアドファンクション、ストアドプログラム、PL/SQLを記述する場合に括弧(カッコ)代わりに使うケースのほか、トランザクションの開始を表す目的で使います。
SQLのBEGIN構文
SQL ServerやAzure SQL Database、Oracle、ProgreSQLでは、一般のSQLの中にBEGIN~ENDを使ったトランザクションを記述できます。
OracleでのBEGIN構文
Oracleでは、PL/SQLサブプログラムを記述する際に、BEGINとENDで囲む必要があります。PL/SQL記述中はセミコロン「;」は単に行の区切りとみなされるため実行されません。
ドット「.」でPL/SQL入力の終わりを指定し、スラッシュ「/」で実行する必要があります。
DECLARE x NUMBER := 100; BEGIN FOR i IN 1..10 LOOP IF MOD (i, 2) = 0 THEN --i is even INSERT INTO temp VALUES (i, x, 'i is even'); ELSE INSERT INTO temp VALUES (i, x, 'i is odd'); END IF; x := x + 100; END LOOP; END; . /
また、Oracleではトランザクションの開始が、他のデータベースと違ってBEGINではなく、SQL規格で定義されたSET TRANSACTIONとなっています。
【関連記事】
▶SQLとはどういうもの? 独自拡張と標準SQLの大きな違いって、何?
SQL ServerでのBEGIN構文
SQL Serverでは、BEGINはSQLブロックの開始として使用します。Azure SQL Databaseでも同様です。
BEGIN { sql_statement | statement_block } END
SQL Serverでのストアドプロシジャ記述は、OracleやMySQLのようなデリミタの置き換えは不要です。以下のように、ストアドプロシジャの宣言部と定義部をASで区切って記述します。
USE AdventureWorks2012; GO CREATE PROCEDURE HumanResources.uspGetEmployeesTest2 @LastName nvarchar(50), @FirstName nvarchar(50) AS SET NOCOUNT ON; SELECT FirstName, LastName, Department FROM HumanResources.vEmployeeDepartmentHistory WHERE FirstName = @FirstName AND LastName = @LastName AND EndDate IS NULL; GO
参考)ストアド プロシージャの作成 – SQL Server | Microsoft Docs
また、トランザクションを明示する場合は、BEGIN TRANSACTOINを使用します。明示しない場合は、SQLを実行するごとに更新内容がテーブルに反映されます。
MySQLのBEGIN構文
MySQLでは、ストアドプログラムを記述する際、プログラムの開始と終了をBEGINとENDで囲む必要があります。
CREATE PROCEDURE dorepeat(p1 INT) BEGIN SET @x = 0; REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; END;
参考)MySQL :: MySQL 5.6 リファレンスマニュアル :: 20.1 ストアドプログラムの定義
ただし、上記をそのまま実行するとセミコロン「;」が区切り文字として実行され、SET @x = 0;の時点で入力内容がサーバに送信されてエラーとなってしまいます。そのため、区切り文字を再定義する必要があります。
mysql> delimiter // mysql> CREATE PROCEDURE dorepeat(p1 INT) -> BEGIN -> SET @x = 0; -> REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; -> END -> // Query OK, 0 rows affected (0.00 sec) mysql> delimiter ;
上記SQLでは、区切り文字(delimiter)をいったん「//」に置き換えたあとストアドプログラムを記述し、「//」でサーバに送信してストアドプログラムを登録しています。登録後、区切り文字をセミコロン「;」に戻しています。
また、MySQLでのトランザクションにもBEGIN(またはSTART TRANSACTOIN)を使用します。デフォルトでは、SQLが実行されると即テーブルに反映する自動コミットモードが有効になっています。
PostgreSQLでのBEGIN構文
PostgreSQLでは、トランザクションの開始をBEGINと記述します。
BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ] transaction_modeは以下のいずれかです。 ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } READ WRITE | READ ONLY [ NOT ] DEFERRABLE
BEGINと、BEGIN WORK、BEGIN TRANSACON、START TRANSACTOINは全て同じ意味になります。
また、PL/SQLを記述する際は、以下のようにBEGINとENDをカッコ代わりに使います。
DECLARE date_string VARCHAR2(10); BEGIN SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD') INTO date_string FROM DUAL; DBMS_OUTPUT.PUT_LINE(date_string); END;
まとめ
- SQLのBEGINには、ストアドプロシジャなどの記述の開始を表す意味と、トランザクションの開始を表す2通りがある。
- ストアドプロシジャ、PL/SQLの記述にはBEGINに対応したENDを記述する。
- トランザクションの開始を表すBEGINは、SQL規格の標準ではSTART TRANSACTIONと同等。