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.