Partilhar via


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

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse AnalyticsSistema de Plataforma de Análise (PDW)Ponto de Extremidade de Análise SQL no Microsoft FabricArmazém no Microsoft FabricBase de Dados SQL no Microsoft Fabric

Envolve uma sequência de instruções Transact-SQL num bloco lógico de código. Esta utilização de BEGIN não está relacionada com as BEGIN TRANSACTION instruções e (e BEGIN ATOMIC ).

Pode usar BEGIN...END blocos com uma instrução de controlo de fluxo anterior, como IF, ELSE, e WHILE. No entanto, também pode usar estes blocos sem qualquer instrução de controlo 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 âmbito lexical.

Transact-SQL convenções de sintaxe

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ção.

Remarks

Um BEGIN...END bloco deve conter pelo menos uma afirmação. Se tentares usar um bloco vazio BEGIN...END , recebes um erro de sintaxe, mesmo que uses um ponto e vírgula após cada palavra-chave. Pode evitar blocos vazios BEGIN...END usando uma GOTO etiqueta como declaração provisória. Ver Exemplo C: Use um rótulo GOTO para BEGIN... gerado dinamicamente... END blocos.

BEGIN...END os blocos podem ser aninhados.

BEGIN...END Os blocos não definem qualquer âmbito lexical. Se declarares uma variável dentro de um bloco, ela é visível em todo o batch pai, não apenas dentro do bloco que contém a DECLARE instrução.

Não podes usar BEGIN...END blocos em vários lotes. Por exemplo, não podes usar o GO separador por lotes 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 corram atómicamente. Quando um batch é executado fora de uma transação e surge um erro ou uma exceção é lançada pela segunda instrução de um bloco multistatement BEGIN...END , a primeira statement não é revertida.

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

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

  • Precisas 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 afirmação subsequente, particularmente uma WITH palavra-chave ou THROW sentença, não precisa de um ponto e vírgula anterior.

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

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que pode ser descarregado da página inicial de Exemplos e Projetos da Comunidade do Microsoft SQL Server.

No exemplo seguinte, BEGIN e END definam sequências de instruções Transact-SQL logicamente relacionadas a executar por 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. Usa BEGIN... FIM numa transação

No exemplo a seguir, BEGIN e END defina uma série de Transact-SQL instruções que são executadas juntas. 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 devolvidas.

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 FINAIS

Se gerar Transact-SQL dinâmicos com um BEGIN...END bloco e quiser que o seu programa represente sempre as BEGIN...END palavras-chave, pode usar um GOTO rótulo como uma instrução marcante para evitar ter um bloco vazio BEGIN...END .

BEGIN
    unusedLabel:
END

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

C. Defina uma série de afirmações que correm juntas

No exemplo a seguir, BEGIN e END defina uma série de instruções SQL que são executadas juntas.

Atenção

Se remover as BEGIN palavras-chave e, END o exemplo seguinte corre num ciclo infinito. A WHILE instrução repete apenas a SELECT consulta em loop 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