sql >> Database >  >> RDS >> Sqlserver

Unieke kolom voor automatisch verhogen van SQL Server in de context van een andere kolom

Welnu, er is geen native ondersteuning voor dit type kolom, maar je zou het kunnen implementeren met een trigger:

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

Niet getest, maar ik ben er vrij zeker van dat het zal werken. Als u een primaire sleutel heeft, kunt u deze ook implementeren als een AFTER trigger (ik gebruik niet graag INSTEAD OF triggers, ze zijn moeilijker te begrijpen wanneer u ze 6 maanden later moet wijzigen).

Gewoon om uit te leggen wat hier aan de hand is:

  • SERIALIZABLE is de strengste isolatiemodus; het garandeert dat slechts één databasetransactie tegelijk deze instructies kan uitvoeren, die we nodig hebben om de integriteit van deze "reeks" te garanderen. Houd er rekening mee dat dit de hele transactie onomkeerbaar promoot, dus u wilt dit niet gebruiken binnen een langlopende transactie.

  • De CTE haalt het hoogste nummer op dat al is gebruikt voor elke ouder-ID;

  • ROW_NUMBER genereert een unieke reeks voor elke ouder-ID (PARTITION BY ) beginnend bij het cijfer 1; we voegen dit toe aan het vorige maximum als er een is om de nieuwe reeks te krijgen.

Ik moet waarschijnlijk ook vermelden dat als je maar één nieuwe onderliggende entiteit tegelijk hoeft in te voegen, je die bewerkingen beter gewoon door een opgeslagen procedure kunt leiden in plaats van een trigger te gebruiken - je zult er zeker betere prestaties uit halen . Dit is hoe het momenteel wordt gedaan met hierarchyid kolommen in SQL '08.



  1. Hoe kan ik JOIN gebruiken in de UPDATE-instructie?

  2. Kan de waarde voor automatisch verhogen van de opslagengine niet lezen, foutnummer:1467

  3. Symfony2 creëren en onderhouden van entiteitsrelaties

  4. Linker join met een duidelijke vraag in Laravel