Megosztás a következőn keresztül:


KEZDŐDIK... VÉGE (Transact-SQL)

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példányAzure Synapse AnalyticsElemzési platformrendszer (PDW)SQL Analytics-végpont a Microsoft FabricbenRaktár a Microsoft FabricbenSQL-adatbázis a Microsoft Fabricben

Egy Transact-SQL állítássorozatot zár be egy logikai kódblokkba. Ez a kifejezés BEGIN nem kapcsolódik az BEGIN TRANSACTION és BEGIN ATOMIC állításokhoz.

Használhatsz BEGIN...END olyan blokkokat, amelyek előzőleg egy áramlásvezérlő utasítást tartalmaznak, például IF, ELSE, és WHILE. Ugyanakkor ezeket a blokkokat felhasználhatod anélkül, hogy bármilyen előzetes folyamatvezérlő állítást használnál, hogy szervezett módon csoportosítsuk a mondatok sorozatait. Azonban minden új BEGIN...END blokk nem hoz létre új lexikai keretet.

Transact-SQL szintaxis konvenciók

Syntax

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

Arguments

{ sql_statement | statement_block }

Bármely érvényes Transact-SQL utasítás vagy utasításcsoportozás egy utasításblokk használatával definiálva.

Remarks

Egy BEGIN...END blokknak legalább egy állítást kell tartalmaznia. Ha üres BEGIN...END blokkot próbálsz használni, szintaxishiba jelentkezik, még akkor is, ha minden kulcsszó után félvesszőt használsz. Elkerülheted az üres BEGIN...END blokkokat, ha egy GOTO címkét használsz helykifejező állításként. Lásd a C példát: Használj GOTO címkét dinamikusan generált BEGIN-hez... END blokkok.

BEGIN...END blokkok beágyazhatók.

BEGIN...END A blokkok nem határoznak meg semmilyen lexikai keretet. Ha egy változót egy blokkon belül bejelentesz, az az egész szülői csomagban látható, nem csak a blokkban, ahol az DECLARE állítás található.

Nem lehet BEGIN...END blokkokat használni több adag között. Például nem használhatod a GO csomagelválasztót egy BEGIN...END blokk belse.

Ha blokk BEGIN...END használunk csoportosításra, az nem jelenti azt, hogy a csoport összes állítása atomilagosan fut. Amikor egy batch a tranzakción kívül fut, és hiba keletkezik, vagy kivételt dob a többmondatú BEGIN...END blokk második állítása, az első utasítás nem jelenik meg.

A kulcsszavak END után jelző BEGIN szemeskolt opcionális, de ajánlott, kivéve az alábbi eseteket:

  • Kell egy szemeskolt a WITH kulcsszó előtt, amely elindítja a közös táblakifejezést (CTE).

  • Szükséged van egy helyes egyenesszékre, amelynek blokkban van egy THROW állítása.

  • Használj utána egy szemespillet BEGIN , hogy elkerüld a félreértést az BEGIN TRANSACTION or BEGIN ATOMIC utasításokkal.

  • A következő célzó END használatával biztosítjuk, hogy a következő állítások, különösen egy WITH kulcsszó vagy THROW állítás, ne legyen szükség előzetes pontosérre.

Bár minden Transact-SQL utasítás érvényes egy BEGIN...END blokkon belül, bizonyos Transact-SQL utasításokat nem szabad csoportosítani ugyanabban a tételben vagy kijelentésblokkban. Győződj meg róla, hogy a kijelentések ne ütközjenek a meglévő Transact-SQL tételi követelményekkel.

Examples

A cikkben szereplő kódminták a AdventureWorks2025 vagy AdventureWorksDW2025 mintaadatbázist használják, amelyet a Microsoft SQL Server-minták és közösségi projektek kezdőlapjáról tölthet le.

A következő példában BEGINEND definiáljuk a logikailag kapcsolódó Transact-SQL állítások sorrendjét, amelyeket sorrendben kell végrehajtani. A példa beágyazott blokkokat is mutat.

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. Használd a BEGIN... VÉGE egy tranzakcióban

Az alábbi példában BEGINEND definiáljon egy Transact-SQL utasítássorozatot, amely együtt hajt végre. Ha a BEGIN...END blokk nincs benne, mindkét ROLLBACK TRANSACTION állítás végrehajtásra kerül, és mindkét PRINT üzenet visszaküld.

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. Használj GOTO címkét a dinamikusan generált BEGIN-hez... END blokkok

Ha dinamikus Transact-SQL generálsz egy BEGIN...END blokkkal, és azt szeretnéd, hogy a programod mindig megjelenítse a BEGIN...END kulcsszavakat, akkor egy GOTO címkét használhatsz helykitöltő utasításként, hogy elkerüld az üres BEGIN...END blokkot.

BEGIN
    unusedLabel:
END

Példák: Azure Synapse Analytics and Analytics Platform System (PDW)

C. Definiáljunk egy együttfutó állítássorozatot

Az alábbi példában BEGINEND definiáljon egy több, együtt futó SQL-utasítást.

Caution

Ha eltávolítod az BEGIN és END kulcsszavakat, a következő példa végtelen körben fut. Az WHILE utasítás csak a SELECT lekérdezést körbezi, és soha nem jut el a SET @Iteration += 1 kijelentéshez.

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

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