sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server unik kolumn för automatisk inkrementering i en annan kolumn

Tja, det finns inget inbyggt stöd för den här typen av kolumner, men du kan implementera det med en utlösare:

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

Inte testat men jag är ganska säker på att det kommer att fungera. Om du har en primärnyckel kan du även implementera denna som en AFTER trigger (jag ogillar att använda INSTEAD OF utlösare är de svårare att förstå när du behöver ändra dem 6 månader senare).

Bara för att förklara vad som händer här:

  • SERIALIZABLE är det strängaste isoleringsläget; det garanterar att endast en databastransaktion åt gången kan exekvera dessa uttalanden, vilket vi behöver för att garantera integriteten för denna "sekvens". Observera att detta oåterkalleligt främjar hela transaktionen, så du vill inte använda detta i en långvarig transaktion.

  • CTE:n hämtar det högsta numret som redan används för varje förälder-ID;

  • ROW_NUMBER genererar en unik sekvens för varje förälder-ID (PARTITION BY ) från siffran 1; vi lägger till detta till det tidigare maximum om det finns en för att få den nya sekvensen.

Jag borde nog också nämna att om du bara behöver infoga en ny underordnad enhet åt gången, är det bättre att du bara kanalisera dessa operationer genom en lagrad procedur istället för att använda en trigger - du kommer definitivt att få bättre prestanda av det . Så här görs det för närvarande med hierarchyid kolumner i SQL '08.



  1. Hur QUOTE() fungerar i MariaDB

  2. Kan inte släppa temptabellen i Postgres-funktionen:används av aktiva frågor i den här sessionen

  3. Laravel frågebyggare - återanvänd fråga med ändrad where-sats

  4. Konvertera Oracle Reports (.rdf) till BIRT-rapporter