模拟插入触发器中的标识列

时间:2010-05-28 17:10:36

标签: sql sql-server-2005 tsql

我有一个需要日志ID的日志记录表,但我不能使用标识列,因为日志ID是组合键的一部分。

create table StuffLogs
{
   StuffID int
   LogID int
   Note varchar(255)
}

StuffID&组合键有一个组合键LogID

我想构建一个插入触发器,在插入日志记录时计算下一个LogID。我可以一次创建一条记录(见下面看看如何计算LogID),但这并不是真正有效,我希望有一种方法可以在没有游标的情况下做到这一点。

select @NextLogID = isnull(max(LogID),0)+1 
from StuffLogs where StuffID = (select StuffID from inserted)

净结果应该允许我在StuffLogs中插入任意数量的记录,并自动计算LogID列。

StuffID  LogID  Note
123      1      foo
123      2      bar
456      1      boo
789      1      hoo

使用StuffID: 123, Note: bop插入另一条记录将产生以下记录:

StuffID  LogID  Note
123      3      bop

3 个答案:

答案 0 :(得分:3)

除非有严格的商业原因要求每个LogID都是从每个不同的StuffID的1开始的序列,否则只需使用一个标识。使用标识,您仍然可以使用StuffID + LogID正确地排序行,但是您不会尝试手动执行插入问题(并发,死锁,锁定/阻塞,慢插入等)。

答案 1 :(得分:0)

Select Row_Number() Over( Order By LogId ) + MaxValue.LogId + 1
From inserted
    Cross Join ( Select Max(LogId)  As Id From StuffLogs ) As MaxValue

您需要对此进行全面测试,并确保如果在LogId上没有发生冲突的同时将两个连接插入到表中。

答案 2 :(得分:0)

确保LogId的默认值为NULL,因此在插入语句期间不需要提供它,就像它是标识列一样。

CREATE TRIGGER Insert ON dbo.StuffLogs
INSTEAD OF INSERT
AS
UPDATE #Inserted SET LogId = select max(LogId)+1 from StuffLogs where StuffId=[INSERTED].StuffId