Nun, es gibt keine native Unterstützung für diesen Spaltentyp, aber Sie könnten ihn mit einem Trigger implementieren:
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
Nicht getestet, aber ich bin mir ziemlich sicher, dass es funktionieren wird. Wenn Sie einen Primärschlüssel haben, können Sie diesen auch als AFTER
implementieren trigger (ich mag es nicht, INSTEAD OF
zu verwenden Trigger, sie sind schwerer zu verstehen, wenn Sie sie 6 Monate später ändern müssen).
Nur um zu erklären, was hier vor sich geht:
-
SERIALIZABLE
ist der strengste Isolationsmodus; es garantiert, dass jeweils nur eine Datenbanktransaktion diese Anweisungen ausführen kann, die wir benötigen, um die Integrität dieser "Sequenz" zu gewährleisten. Beachten Sie, dass dies die gesamte Transaktion irreversibel fördert, sodass Sie dies nicht innerhalb einer Transaktion mit langer Laufzeit verwenden möchten. -
Der CTE nimmt die höchste bereits verwendete Nummer für jede Eltern-ID auf;
-
ROW_NUMBER
generiert eine eindeutige Sequenz für jede Eltern-ID (PARTITION BY
) beginnend mit der Nummer 1; Wir addieren dies zum vorherigen Maximum, falls es eines gibt, um die neue Sequenz zu erhalten.
Ich sollte wahrscheinlich auch erwähnen, dass Sie, wenn Sie immer nur eine neue untergeordnete Entität auf einmal einfügen müssen, diese Operationen besser durch eine gespeicherte Prozedur leiten, anstatt einen Trigger zu verwenden - Sie werden definitiv eine bessere Leistung erzielen . So wird es derzeit mit hierarchyid
gemacht Spalten in SQL '08.