SQL而不是触发器有时不会触发?

Posted

技术标签:

【中文标题】SQL而不是触发器有时不会触发?【英文标题】:SQL Instead of trigger is not fireing sometimes? 【发布时间】:2011-01-21 14:26:30 【问题描述】:

表事件有一个而不是触发器,其目的是生成主键EventId为Max+1,其余列由插入填充。

EventId 不是Identity,我们不能让它成为identity,因为那里有很多依赖,触发逻辑:

SELECT TOP 1 @ID = Event.EventID FROM Event
IF (@ID IS NULL)
BEGIN
  SET @ID=1
END
ELSE
BEGIN
  SELECT @ID = MAX(Event.EventID) FROM Event
  SET @ID=@ID+1
END
--Then just a insert statment with this id as EventId and rest of the columns from inserted table

现在有时当我尝试插入此表时,它仍然说无法在 eventId 中插入重复项,不知道为什么会发生这种情况...

看起来在某些情况下触发器没有触发?为什么

【问题讨论】:

【参考方案1】:

您可能假设插入的伪表中有一行,并且在发生多行插入时失败。

你想要这样的东西:

;with maxID as (
    select MAX(EventID) as EventID from Event
), nrows as (
    select
        ROW_NUMBER() OVER (ORDER BY newid()) +
            COALESCE((select EventID from maxID),0) as EventID,
        /* columns from inserted table */
    from inserted
)
insert into Event (EventID,/* other columns */)
select EventID,/* other columns */
from nrows

【讨论】:

这就像上帝一样工作,但你能解释一下以前的逻辑有什么问题吗?是因为表锁吗? @Lalit - 老实说,我正在解决(可能)错误的问题 - 我认为您可能会在单个 INSERT 语句中将多行插入表中。但我相信上面的答案,因为它处理整个“搜索 MAX,基于它计算出新的 ID 值,插入新值”作为单个语句 - 所以你不需要搞砸锁定提示或更改隔离级别。 是的,我正在使用 INSERT INTO EVENT SELECT EVENTID,NAME FROM TMP_TABLE_TYPE,所以一次插入多条记录。【参考方案2】:

您需要使用某种锁定来防止生成重复 ID。查看this thread 的类似问题,了解如何解决此问题。

【讨论】:

是的,我使用 2008 的表类型插入这个,所以一次插入一堆记录。

以上是关于SQL而不是触发器有时不会触发?的主要内容,如果未能解决你的问题,请参考以下文章

SQL/触发器:延迟后显示的输出

sql MS SQL而不是触发器

为什么有时候人们用translate来改变位置而不是定位?

触发存储过程运行而不是 INSERT (PL/SQL)

而不是 SQL Server 中的触发器丢失 SCOPE_IDENTITY?

而不是SQL Server中的触发器丢失SCOPE_IDENTITY?