Delen via


BEGINNEN... EINDE (Transact-SQL)

Van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL Analytics-eindpunt in Microsoft FabricMagazijn in Microsoft FabricSQL-database in Microsoft Fabric

Sluit een reeks Transact-SQL statements in in een logisch blok code. Dit gebruik van BEGIN staat los van de BEGIN TRANSACTION en-uitspraken BEGIN ATOMIC .

Je kunt blokken gebruiken BEGIN...END met een voorafgaande flow-control instructie zoals IF, ELSE, en WHILE. Je kunt deze blokken echter ook gebruiken zonder voorafgaande flow-control-instructie om reeksen statements op een georganiseerde manier te groeperen. Echter, elk nieuw BEGIN...END blok creëert geen nieuw lexicale bereik.

Transact-SQL syntaxis-conventies

Syntax

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

Arguments

{ sql_statement | statement_block }

Elke geldige Transact-SQL instructie of instructiegroepering zoals gedefinieerd met behulp van een instructieblok.

Remarks

Een BEGIN...END blok moet ten minste één statement bevatten. Als je probeert een leeg BEGIN...END blok te gebruiken, krijg je een syntaxisfout, zelfs als je een puntkomma na elk trefwoord gebruikt. Je kunt lege BEGIN...END blokken vermijden door een GOTO label als tijdelijke instructie te gebruiken. Zie voorbeeld C: Gebruik een GOTO-label voor dynamisch gegenereerde BEGIN... EINDE blokken.

BEGIN...END blokken kunnen worden genest.

BEGIN...END blokken definiëren geen lexicale reikwijdte. Als je een variabele declareert binnen een blok, is deze zichtbaar in de hele ouderbatch, niet alleen binnen het blok met de DECLARE instructie.

Je kunt geen blokken gebruiken BEGIN...END over meerdere batches. Je kunt bijvoorbeeld de GO batchseparator niet binnen een BEGIN...END blok gebruiken.

Het gebruik van een BEGIN...END block to group-statements betekent niet dat alle statements in de groep atomair draaien. Wanneer een batch buiten een transactie draait en er wordt een fout geactiveerd of een uitzondering wordt gegooid door de tweede instructie van een multistatementblok BEGIN...END , wordt de eerste instructie niet teruggerold.

Puntkomma's na de BEGIN en END trefwoorden zijn optioneel, maar worden aanbevolen, behalve in de volgende gevallen:

  • Je hebt een puntkomma nodig vóór het WITH trefwoord dat een common table-expressie (CTE) start.

  • Je hebt een puntkomma nodig met een THROW statement binnen een blok.

  • Gebruik daarna een puntkomma BEGIN om verwarring met de BEGIN TRANSACTION of statements BEGIN ATOMIC te voorkomen.

  • Het gebruik van een puntkomma na END zorgt ervoor dat elke volgende uitspraak, met name een WITH trefwoord of THROW uitspraak, geen voorafgaande puntkomma' nodig heeft.

Hoewel alle Transact-SQL statements geldig zijn binnen een BEGIN...END blok, moet je bepaalde Transact-SQL statements niet samen groeperen binnen dezelfde batch of statementblok. Zorg ervoor dat verklaringen niet conflicteren met bestaande Transact-SQL batchvereisten.

Examples

De codevoorbeelden in dit artikel gebruiken de AdventureWorks2025 of AdventureWorksDW2025 voorbeelddatabase die u kunt downloaden van de startpagina van Microsoft SQL Server Samples en Community Projects .

In het volgende voorbeeld BEGIN definieer en END reeksen van logisch gerelateerde Transact-SQL-statements die in volgorde uitgevoerd moeten worden. Het voorbeeld toont ook geneste blokken.

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. Gebruik BEGIN... END in een transactie

In het volgende voorbeeld BEGINEND definieert u een reeks Transact-SQL instructies die samen worden uitgevoerd. Als het BEGIN...END blok niet is opgenomen, worden beide ROLLBACK TRANSACTION statements uitgevoerd en worden beide PRINT berichten teruggegeven.

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. Gebruik een GOTO-label voor dynamisch gegenereerde BEGIN... EINDBLOKKEN

Als je dynamische Transact-SQL genereert met een BEGIN...END blok en je wilt dat je programma altijd de BEGIN...END trefwoorden rendert, kun je een GOTO label als tijdelijke aanduiding gebruiken om een leeg BEGIN...END blok te voorkomen.

BEGIN
    unusedLabel:
END

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

C. Definieer een reeks uitspraken die samen lopen

In het volgende voorbeeld BEGIN definieert END u een reeks SQL-instructies die samen worden uitgevoerd.

Waarschuwing

Als je de en-trefwoorden BEGINEND verwijdert, draait het volgende voorbeeld in een oneindige lus. De WHILE instructie loopt alleen de SELECT query en bereikt nooit de SET @Iteration += 1 stelling.

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

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