Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cột tăng tự động duy nhất của SQL Server trong ngữ cảnh của một cột khác

Chà, không có hỗ trợ gốc nào cho loại cột này, nhưng bạn có thể triển khai nó bằng cách sử dụng trình kích hoạt:

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

Chưa được thử nghiệm nhưng tôi khá chắc chắn rằng nó sẽ hoạt động. Nếu bạn có khóa chính, bạn cũng có thể triển khai khóa này dưới dạng AFTER trigger (Tôi không thích sử dụng INSTEAD OF kích hoạt, chúng khó hiểu hơn khi bạn cần sửa đổi chúng 6 tháng sau).

Chỉ để giải thích những gì đang xảy ra ở đây:

  • SERIALIZABLE là chế độ cách ly nghiêm ngặt nhất; nó đảm bảo rằng chỉ một giao dịch cơ sở dữ liệu tại một thời điểm có thể thực hiện các câu lệnh này, mà chúng tôi cần để đảm bảo tính toàn vẹn của "chuỗi" này. Lưu ý rằng điều này không thể thay đổi thúc đẩy toàn bộ giao dịch, vì vậy bạn sẽ không muốn sử dụng điều này trong một giao dịch dài hạn.

  • CTE chọn số cao nhất đã được sử dụng cho mỗi ID mẹ;

  • ROW_NUMBER tạo một chuỗi duy nhất cho mỗi ID mẹ (PARTITION BY ) bắt đầu từ số 1; chúng tôi thêm giá trị này vào giá trị tối đa trước đó nếu có một giá trị để có được chuỗi mới.

Tôi có lẽ cũng nên đề cập rằng nếu bạn chỉ cần chèn một thực thể con mới tại một thời điểm, thì tốt hơn hết bạn chỉ nên tạo các thao tác đó thông qua một quy trình được lưu trữ thay vì sử dụng trình kích hoạt - bạn chắc chắn sẽ nhận được hiệu suất tốt hơn từ nó . Đây là cách nó hiện được thực hiện với hierarchyid các cột trong 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. Cột có chức năng DEFAULT, truyền tham số hoặc xác định giá trị chèn?

  2. SQL động (chuyển tên bảng làm tham số)

  3. Cách lấy giá trị theo trường động Tên bằng truy vấn sql select

  4. trường đếm to_sql pyodbc không chính xác hoặc lỗi cú pháp

  5. Làm cách nào để chuyển hàng thành cột trong sql server 2005