Compartir vía


EMPEZAR... FIN (Transact-SQL)

Se aplica a:SQL ServerAzure SQL DatabaseInstancia administrada de Azure SQLAzure Synapse AnalyticsAnalytics Platform System (PDW)Punto de conexión de SQL Analytics en Microsoft FabricAlmacén en Microsoft FabricBase de datos SQL en Microsoft Fabric

Encierra una secuencia de sentencias Transact-SQL en un bloque lógico de código. Este uso de BEGIN no está relacionado con las BEGIN TRANSACTION sentencias y (y BEGIN ATOMIC ).

Puedes usar BEGIN...END bloques con una sentencia de control de flujo anterior como IF, ELSE, y WHILE. Sin embargo, también puedes usar estos bloques sin ninguna instrucción de control de flujo previa para agrupar secuencias de sentencias de forma organizada. Sin embargo, cada nuevo BEGIN...END bloque no crea un nuevo ámbito léxico.

Convenciones de sintaxis de Transact-SQL

Syntax

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

Arguments

{ sql_statement | statement_block}

Cualquier instrucción transact-SQL válida o agrupación de instrucciones tal como se define mediante un bloque de instrucciones.

Remarks

Un BEGIN...END bloque debe contener al menos una sentencia. Si intentas usar un bloque vacío BEGIN...END , obtienes un error de sintaxis, incluso si usas punto y coma después de cada palabra clave. Puedes evitar bloques vacíos BEGIN...END usando una GOTO etiqueta como declaración provisional. Ver Ejemplo C: Usar una etiqueta GOTO para BEGIN... generado dinámicamente. END bloques.

BEGIN...END los bloques se pueden anidar.

BEGIN...END Los bloques no definen ningún alcance léxico. Si declaras una variable dentro de un bloque, es visible en todo el lote padre, no solo dentro del bloque que contiene la DECLARE sentencia.

No puedes usar BEGIN...END bloques de varios lotes. Por ejemplo, no puedes usar el GO separador por lotes dentro de un BEGIN...END bloque.

Usar un BEGIN...END bloque para agrupar sentencias no significa que todas las sentencias del grupo se ejecuten atómicamente. Cuando un lote se ejecuta fuera de una transacción y se genera un error o se lanza una excepción con la segunda sentencia de un bloque de varias instrucciones BEGIN...END , la primera sentencia no se revierte.

Las palabras clave con punto y coma después de y BEGINEND son opcionales pero recomendadas, salvo en los siguientes casos:

  • Necesitas un punto y coma antes de la WITH palabra clave que inicia una expresión común de tabla (CTE).

  • Necesitas un punto y coma con una THROW declaración dentro de un bloque.

  • Usa un punto y coma después BEGIN para evitar confusiones con las BEGIN TRANSACTION sentencias o BEGIN ATOMIC .

  • Usar un punto y coma después END garantiza que cualquier afirmación posterior, especialmente una WITH palabra clave o THROW sentencia, no necesite un punto y coma anterior.

Aunque todas las sentencias Transact-SQL son válidas dentro de un BEGIN...END bloque, no deberías agrupar ciertas sentencias de Transact-SQL dentro del mismo lote o bloque de instrucciones. Asegúrate de que los estados de cuenta no entren en conflicto con los requisitos existentes de Transact-SQL lote.

Examples

Los ejemplos de código de este artículo usan la base de datos de ejemplo de AdventureWorks2025 o AdventureWorksDW2025, que puede descargar de la página principal de Ejemplos de Microsoft SQL Server y proyectos de comunidad.

En el siguiente ejemplo, BEGIN y END definimos secuencias de sentencias de Transact-SQL lógicamente relacionadas que deben ejecutarse en orden. El ejemplo también muestra bloques anidados.

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. Usa BEGIN... FIN en una transacción

En el siguiente ejemplo, BEGIN y END definen un conjunto de instrucciones Transact-SQL que se ejecutan juntas. Si el BEGIN...END bloque no está incluido, ambas ROLLBACK TRANSACTION sentencias se ejecutan y ambos PRINT mensajes se devuelven.

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. Usa una etiqueta GOTO para BEGIN... generado dinámicamente. BLOQUES FINALES

Si generas Transact-SQL dinámicas con un BEGIN...END bloque y quieres que tu programa siempre muestre las BEGIN...END palabras clave, puedes usar una GOTO etiqueta como sentencia marcadora para evitar tener un bloque vacío BEGIN...END .

BEGIN
    unusedLabel:
END

Ejemplos: Azure Synapse Analytics y Sistema de la plataforma de análisis (PDW)

C. Definamos una serie de sentencias que se juntan

En el siguiente ejemplo, BEGIN y END definen un conjunto de instrucciones SQL que se ejecutan juntas.

Precaución

Si eliminas las BEGIN palabras clave y END , el siguiente ejemplo se ejecuta en un bucle infinito. La WHILE sentencia solo se repite la SELECT consulta y nunca llega a ella 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