sql >> Databáze >  >> RDS >> Sqlserver

Jedinečný sloupec automatického přírůstku serveru SQL Server v kontextu jiného sloupce

No, pro tento typ sloupců neexistuje žádná nativní podpora, ale můžete jej implementovat pomocí spouštěče:

CREATE TRIGGER tr_MyTable_Number
ON MyTable
INSTEAD OF INSERT
AS

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN;

WITH MaxNumbers_CTE AS
(
    SELECT ParentEntityID, MAX(Number) AS Number
    FROM MyTable
    WHERE ParentEntityID IN (SELECT ParentEntityID FROM inserted)
)
INSERT MyTable (ParentEntityID, Number)
    SELECT
        i.ParentEntityID,
        ROW_NUMBER() OVER
        (
            PARTITION BY i.ParentEntityID
            ORDER BY (SELECT 1)
        ) + ISNULL(m.Number, 0) AS Number
    FROM inserted i
    LEFT JOIN MaxNumbers_CTE m
        ON m.ParentEntityID = i.ParentEntityID

COMMIT

Netestováno, ale jsem si jistý, že to bude fungovat. Pokud máte primární klíč, můžete jej implementovat také jako AFTER spoušť (Nerad používám INSTEAD OF spouštěče, jsou hůře srozumitelné, když je potřebujete upravit o 6 měsíců později).

Jen pro vysvětlení, co se tady děje:

  • SERIALIZABLE je nejpřísnější režim izolace; zaručuje, že pouze jedna databázová transakce může provádět tyto příkazy, což potřebujeme, abychom zaručili integritu této "sekvence." Všimněte si, že to nevratně propaguje celou transakci, takže to nebudete chtít použít v rámci dlouhotrvající transakce.

  • CTE vybere nejvyšší číslo, které již bylo použito pro každé rodičovské ID;

  • ROW_NUMBER vygeneruje jedinečnou sekvenci pro každé rodičovské ID (PARTITION BY ) od čísla 1; přidáme to k předchozímu maximu, pokud existuje jedno, abychom získali novou sekvenci.

Pravděpodobně bych měl také zmínit, že pokud potřebujete vložit pouze jednu novou podřízenou entitu najednou, je lepší, když tyto operace protáhnete uloženou procedurou namísto použití triggeru – určitě z toho získáte lepší výkon. . Takto se to aktuálně dělá s hierarchyid sloupce v SQL '08.



  1. Vložte xmltype do xmltype na určené místo [PL/SQL]

  2. Dělíte tabulky mySQL na oddíly, které mají cizí klíče?

  3. C# Mysql executenonqueryasync není asynchronní

  4. SUPER oprávnění pro tuto operaci