Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Уникална колона за автоматично нарастване на SQL Server в контекста на друга колона

Е, няма собствена поддръжка за този тип колона, но можете да я внедрите с помощта на тригер:

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

Не е тестван, но съм почти сигурен, че ще работи. Ако имате първичен ключ, можете също да приложите това като AFTER тригер (не обичам да използвам INSTEAD OF задействания, те са по-трудни за разбиране, когато трябва да ги промените 6 месеца по-късно).

Само за да обясня какво се случва тук:

  • SERIALIZABLE е най-строгият режим на изолация; той гарантира, че само една транзакция на база данни в даден момент може да изпълни тези изрази, които са ни необходими, за да гарантираме целостта на тази "последователност". Имайте предвид, че това необратимо насърчава цялата транзакция, така че няма да искате да използвате това вътре в дълготрайна транзакция.

  • CTE взема най-голямото вече използвано число за всеки родителски ID;

  • ROW_NUMBER генерира уникална последователност за всеки родителски идентификатор (PARTITION BY ) като се започне от числото 1; добавяме това към предишния максимум, ако има такъв, за да получим новата последователност.

Вероятно трябва също така да спомена, че ако трябва да вмъквате само един нов дъщерен обект наведнъж, по-добре е просто да насочите тези операции през съхранена процедура, вместо да използвате тригер - определено ще получите по-добра производителност от това . Ето как се прави в момента с hierarchyid колони в SQL '08.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да намеря причината за блокиране в sql сървър ro14?

  2. ADO.NET извикването на T-SQL Stored Procedure причинява SqlTimeoutException

  3. Изберете Данни чрез функция с таблично значение в SQL Server

  4. прикачената база данни е само за четене

  5. SQL Server 2008 Пълнотекстово търсене – БАВНО