Syntax\n------\n\n[begin_label:] BEGIN [NOT ATOMIC]\n    [statement_list]\nEND [end_label]\n\nDescription\n-----------\n\nBEGIN ... END syntax is used for writing compound statements. A compound statement can contain multiple statements, enclosed by the BEGIN and END keywords. statement_list represents a list of one or more statements, each terminated by a semicolon (i.e., ;) statement delimiter. statement_list is\\\noptional, which means that the empty compound statement (BEGIN END) is legal.\n\nNote that END will perform a commit. If you are running in autocommit mode, every statement will be committed separately. If you are not running in autocommit mode, you must execute a COMMIT or ROLLBACK after END to get the database up to date.\n\nUse of multiple statements requires that a client is able to send statement strings containing the statement delimiter. This is handled in the mysql command-line client with the DELIMITER command.\\\nChanging the ; end-of-statement delimiter (for example, to//) allows ; to be used in a program body.\n\nA compound statement within a stored program can be labeled. end_label cannot be given unless begin_label also is present. If both are present, they must be the same.\n\nBEGIN ... END constructs can be nested. Each block can define its own variables, a CONDITION, a HANDLER and a CURSOR, which don't exist in the outer blocks. The most local declarations override the outer objects which use the same name (see example below).\n\nThe declarations order is the following:\n\n DECLARE local variables\n DECLARE CONDITIONs\n DECLARE CURSORs\n DECLARE HANDLERs\n\nNote that DECLARE HANDLER contains another BEGIN ... END construct.\n\nHere is an example of a very simple, anonymous block:\n\n``sql\nBEGIN NOT ATOMIC\nSET @a=1;\nCREATE TABLE test.t1(a INT);\nEND|\n`\n\nBelow is an example of nested blocks in a stored procedure:\n\n`sql\nCREATE PROCEDURE t( )\nBEGIN\n   DECLARE x TINYINT UNSIGNED DEFAULT 1;\n   BEGIN\n      DECLARE x CHAR(2) DEFAULT '02';\n       DECLARE y TINYINT UNSIGNED DEFAULT 10;\n       SELECT x, y;\n   END;\n   SELECT x;\nEND;\n`\n\nIn this example, a TINYINT variable, x is declared in the outter block. But in the inner block x is re-declared as a CHAR and an y variable is declared. The inner SELECT shows the "new" value of x, and the value of y. But when x is selected in the outer block, the "old" value is returned. The final SELECT doesn't try to read y`, because it doesn't exist in that context.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/begin-end