我在触发TICKETS表中所有状态更改的日期时使用触发器: 我确实在上面尝试过它,但它正在响应:“无效的对象名称'UPDATED'”。
CREATE TRIGGER TG_TICKETS_STATUS_HISTORY
ON TICKETS_TI AFTER UPDATE
AS
BEGIN
DECLARE @ID INT
DECLARE @STATUS INT
SELECT @ID = ID,
@STATUS = STATUS
FROM UPDATED
IF (@STATUS != (
SELECT TOP 1 SH.STS_NAME
FROM TICKETS_STATUS_HISTORY SH
WHERE SH.ID = @ID
ORDER BY SH.STS_DATE DESC
))
BEGIN
INSERT INTO TICKETS_STATUS_HISTORY
VALUES (@ID, @STATUS, GETDATE())
END
END
答案 0 :(得分:2)
你应该拥有的是:
CREATE TRIGGER TG_TICKETS_STATUS_HISTORY
ON TICKETS_TI AFTER UPDATE
AS
BEGIN
INSERT INTO TICKETS_STATUS_HISTORY (ID,STS_NAME,STS_DATE)
select i.ID,i.Status,GETDATE()
from inserted i
inner join (
select ID,STS_NAME,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY STS_DATE desc) as rn
from TICKETS_STATUS_HISTORY
) h
on
i.ID = h.ID and
i.STATUS != h.STS_NAME and
h.rn = 1
END
inserted
(和deleted
)是一个pseudo-table,可以包含0,1或多个行。将列值分配给标量变量(例如
SELECT @ID = ID,
@STATUS = STATUS
FROM INSERTED
)是完全错误的。
如果您只想检查状态列值是否已更改(并且不需要在历史记录表中查找),我们可以使其更简单:
INSERT INTO TICKETS_STATUS_HISTORY (ID,STS_NAME,STS_DATE)
select i.ID,i.Status,GETDATE()
from inserted i
inner join
deleted d
on
i.ID = d.ID and
i.STATUS != d.STATUS
答案 1 :(得分:1)
您应该使用INSERTED
表而不是UPDATED
,因为更新操作包括删除操作和插入操作。
在DELETED
表中,您会找到旧的值,在INSERTED
中,您会找到新的(已更新的)值。
此外,在触发器声明中,您应该使用FOR
关键字而不是ON
来引用应该启动触发器的操作。
例如
CREATE TRIGGER TG_TICKETS_STATUS_HISTORY
ON TICKETS_TI
FOR UPDATE
AS
BEGIN
INSERT INTO TICKETS_STATUS_HISTORY
SELECT I.ID, I.STATUS, GETDATE()
FROM INSERTED I
INNER JOIN DELETED D
ON I.ID = D.ID
AND I.STATUS != L.STATUS
END