Compartilhar via


COMEÇAR... FIM (Transact-SQL)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)Ponto de extremidade de análise de SQL no Microsoft FabricDepósito no Microsoft FabricBanco de dados SQL no Microsoft Fabric

Envolve uma sequência de instruções Transact-SQL em um bloco lógico de código. Esse uso de BEGIN não tem relação com as BEGIN TRANSACTION instruções e (e BEGIN ATOMIC ).

Você pode usar BEGIN...END blocos com uma instrução de controle de fluxo anterior, como IF, ELSE, e WHILE. No entanto, você também pode usar esses blocos sem nenhuma instrução de controle de fluxo anterior para agrupar sequências de instruções de forma organizada. No entanto, cada novo BEGIN...END bloco não cria um novo escopo lexical.

Convenções de sintaxe de Transact-SQL

Syntax

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

Arguments

{ sql_statement | statement_block}

Qualquer instrução Transact-SQL válida ou agrupamento de instruções, conforme definido usando um bloco de instruções.

Remarks

Um BEGIN...END bloco deve conter pelo menos uma instrução. Se você tentar usar um bloco vazio BEGIN...END , recebe um erro de sintaxe, mesmo usando um ponto e vírgula após cada palavra-chave. Você pode evitar blocos vazios BEGIN...END usando um GOTO rótulo como uma declaração provisória. Veja o Exemplo C: Use um rótulo GOTO para BEGIN... gerado dinamicamente... END blocos.

BEGIN...END blocos podem ser aninhados.

BEGIN...END Blocos não definem nenhum escopo lexical. Se você declarar uma variável dentro de um bloco, ela fica visível em todo o lote pai, não apenas dentro do bloco que contém a DECLARE instrução.

Você não pode usar BEGIN...END blocos em vários lotes. Por exemplo, você não pode usar o GO separador de lote dentro de um BEGIN...END bloco.

Usar um BEGIN...END bloco para agrupar instruções não significa que todas as instruções do grupo funcionam atômicamente. Quando um lote é executado fora de uma transação e um erro é gerado ou uma exceção é lançada pela segunda instrução de um bloco de múltiplas sentenças BEGIN...END , a primeira instrução não é revertida.

Ponto-vírgulas após as BEGIN palavras-chave e END são opcionais, mas recomendadas, exceto nos seguintes casos:

  • Você precisa de um ponto e vírgula antes da WITH palavra-chave que inicia uma expressão comum de tabela (CTE).

  • Você precisa de um ponto e vírgula com uma THROW instrução dentro de um bloco.

  • Use um ponto e vírgula depois BEGIN para evitar confusão com as BEGIN TRANSACTION instruções ou.BEGIN ATOMIC

  • Usar um ponto e vírgula depois END garante que qualquer instrução subsequente, especialmente uma WITH palavra-chave ou THROW instrução, não precise de ponto e vírgula anterior.

Embora todas as instruções Transact-SQL sejam válidas dentro de um BEGIN...END bloco, você não deve agrupar certas instruções Transact-SQL dentro do mesmo lote ou bloco de instruções. Certifique-se de que extratos não entrem em conflito com os requisitos existentes Transact-SQL lote.

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que você pode baixar na página inicial Microsoft SQL Server Samples and Community Projects.

No exemplo a seguir, BEGIN e END definam sequências de instruções Transact-SQL logicamente relacionadas a serem executadas em ordem. O exemplo também mostra blocos aninhados.

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... FIM em uma transação

No exemplo a seguir, BEGIN e END definem uma série de instruções Transact-SQL que são executadas em conjunto. Se o bloco BEGIN...END não for incluído, ambas ROLLBACK TRANSACTION as instruções são executadas e ambas PRINT as mensagens são retornadas.

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. Use um rótulo GOTO para BEGIN... gerado dinamicamente. Blocos END

Se você gera Transact-SQL dinâmicas com um BEGIN...END bloco e quer que seu programa sempre renderize as BEGIN...END palavras-chave, pode usar um GOTO rótulo como uma instrução marcante para evitar um bloco vazio BEGIN...END .

BEGIN
    unusedLabel:
END

Exemplos: Azure Synapse Analytics e PDW (Analytics Platform System)

C. Defina uma série de afirmações que se juntam

No exemplo a seguir, BEGIN e END definem uma série de instruções do SQL que são executadas em conjunto.

Cuidado

Se você remover as BEGIN palavras-chave e, END o exemplo a seguir roda em um loop infinito. A WHILE instrução repete apenas a SELECT consulta e nunca chega à SET @Iteration += 1 instrução.

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

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