【问题标题】:How to have a table trigger get the current row PK如何让表触发器获取当前行 PK
【发布时间】:2013-07-11 15:16:51
【问题描述】:

我正在尝试为表设置触发器以更新列“持续时间”,即该行的开始日期和结束日期之间的持续时间。但是,每当我插入/更新列时,触发器都不起作用,因为 SCOPE_INDENTITY() 一直返回 null。我该如何解决这个问题?

ALTER TRIGGER [dbo].[CalcDuration]
ON [dbo].[Event]
AFTER INSERT, UPDATE, DELETE 
AS

DECLARE @STARTED datetime
DECLARE @FINISHED datetime
DECLARE @ID int

SELECT @ID = SCOPE_IDENTITY()

SELECT @STARTED  = [Date & Time Started] FROM  dbo.Event WHERE [Event ID] = @ID
SELECT @FINISHED = [Date & Time Finished] FROM dbo.Event WHERE [Event ID] = @ID

UPDATE dbo.Event 
SET Duration = DATEDIFF (  hour, @STARTED, @FINISHED )
WHERE [Event ID] = @ID

【问题讨论】:

  • 为什么不只使用inserteddeleted 伪表?这些表将包含包括 PK 在内的整个记录​​,对于受影响的每一行,即使一次写入多行也是如此...... (注意:更新的行是同时出现在inserteddeleted 中的行。 )

标签: sql sql-server triggers


【解决方案1】:

SCOPE_INDENTITY() 仅返回当前范围内最后插入的标识值,因此如果在触发器内部使用它,它只会在触发器中执行插入操作后返回值 - 这里不是这种情况,因此返回 NULL。

我想您正在尝试获取插入/更新值的 ID,在这种情况下可以使用表 INSERTED

接下来,假设您的触发器只能在单行上工作,您就犯了一个大错误,但通常情况并非如此,因为 UPDATE 和 INSERT 可以在多行上工作。 INSERTED 表幸运地包含所有插入/更新的行。

所以你的触发器应该是这样的:

UPDATE e
SET e.Duration = DATEDIFF (hour, e.[Date & Time Started], e.[Date & Time Finished])
FROM dbo.Event e
INNER JOIN INSERTED i on e.[Event ID] = i.[Event ID]

最后,还要指出这是完全不必要的触发器使用。使用计算列也可以(并且应该)这样做。因此,如果您只是将列更改为:

ALTER TABLE  dbo.Event
ALTER COLUMN [Duration] AS DATEDIFF(hour, [Date & Time Started], [Date & Time Finished])

您将始终拥有正确的持续时间,而无需触发。

【讨论】:

    【解决方案2】:

    如果你坚持使用after 触发器(注意:不需要AFTER DELETE),你可以这样做

    CREATE TRIGGER ai_event
    ON event AFTER INSERT,UPDATE
    as
    BEGIN
    UPDATE event 
    SET  Duration  = DATEDIFF(hour, i.[Date & Time Started],i.[Date & Time Finished])
    from event e 
    INNER JOIN INSERTED i ON (i.id = e.id)
    
    END;
    

    但是,在这种情况下,将Duration 作为计算 [persisted] 列似乎是一个更好的选择...

    ALTER TABLE event ADD Duration2 AS DATEDIFF(hour, [Date & Time Started],
    [Date & Time Finished]) PERSISTED;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多