我编写了一个触发器,当我更新基表中的值时,我在审计表中得到了多个记录。我只期待一个。这是我的触发器:
CREATE TRIGGER dbo.SOP10100_TRDISAMT
ON dbo.SOP10100
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF (select TRDISAMT from inserted) = 0
BEGIN
RETURN
END
ELSE
BEGIN
DECLARE @SOPTYPE smallint = (select soptype from inserted)
DECLARE @SOPNUMBE char(21) = (select sopnumbe from inserted)
DECLARE @MSTRNUMB int = (select mstrnumb from inserted)
DECLARE @DOCID char(15) = (select docid from inserted)
DECLARE @SUBTOTAL numeric(19,5) = (select subtotal from inserted)
DECLARE @MISCAMT numeric(19,5) = (select MISCAMNT from inserted)
DECLARE @TRDISAMT numeric(19,5) = (select TRDISAMT from inserted)
DECLARE @TRDISAMT_B4 numeric(19,5) = (select TRDISAMT from deleted)
DECLARE @FRTAMNT numeric(19,5) = (select FRTAMNT from inserted)
DECLARE @TAXAMNT numeric(19,5) = (select TAXAMNT from inserted)
DECLARE @DOCAMNT numeric(19,5) = (select DOCAMNT from inserted)
DECLARE @USERNAME nvarchar(128) = (select SUSER_SNAME())
DECLARE @TheTime datetime = (select GETDATE())
INSERT INTO SOP10100_TRDISAMT_AUDIT (soptype,sopnumbe,MSTRNUMB,DOCID,SUBTOTAL,MISCAMT,TRDISAMT,TRDISAMT_B4,FRTAMNT,TAXAMNT,DOCAMNT,USERNAME,TheTime)
VALUES (@SOPTYPE,@SOPNUMBE,@MSTRNUMB,@DOCID,@SUBTOTAL,@MISCAMT,@TRDISAMT,@TRDISAMT_B4,@FRTAMNT,@TAXAMNT,@DOCAMNT,@USERNAME,@TheTime)
END
END
这是我运行的更新值:
update SOP10100 set TRDISAMT = 35 where SOPTYPE = 1 and SOPNUMBE = '126535'
这导致两条记录被插入到我的审计表中。想法?
答案 0 :(得分:1)
您的查询存在致命缺陷,因为它没有考虑插入或更新的多行(或零行)。
您的触发器应该看起来像这样:
CREATE TRIGGER dbo.SOP10100_TRDISAMT
ON dbo.SOP10100
AFTER INSERT, UPDATE
AS
INSERT INTO SOP10100_TRDISAMT_AUDIT
(soptype, sopnumbe, MSTRNUMB, DOCID, SUBTOTAL, MISCAMT, TRDISAMT,
TRDISAMT_B4, FRTAMNT, TAXAMNT, DOCAMNT, USERNAME, TheTime)
SELECT i.soptype, i.sopnumbe, i.mstrnumb, i.docid, i.subtotal, i.MISCAMNT, i.TRDISAMT,
i.TRDISAMT, i.FRTAMNT, i.TAXAMNT, i.DOCAMNT, SUSER_SNAME(), GETDATE()
FROM inserted i
WHERE i.TRDISAMT <> 0;
GO
UPDATE
语句根本没有更改值的行,则需要添加EXCEPT
SELECT d.soptype, d.sopnumbe.....
FROM deleted d
char
是一种不常见的数据类型,只能在值固定为该长度的情况下使用,否则会出现尾随空格。