在 MSSQL 中使用触发器跟踪和存储旧值和新值
Track and store old and new value using trigger in MSSQL
我是 MSSQL 的新手,为了跟踪 sql table 中的更改,我创建了一个单独的 table 并在发生任何更改时填充它,我在下面写了这个触发器(目前我正在为插入而写,因此旧值和新值可能看起来很愚蠢,但我需要相同的东西,而任何东西都得到更新)我打算在此之后再写两个用于删除和更新的触发器。
以下是触发代码,但我无法获取旧值,请帮助我:
create trigger ToolHistory_Insert on [Tool Management]
after Insert
as
begin
set nocount on;
declare @oldID int
declare @type nvarchar(20)
declare @material float
declare @matdes nvarchar(MAX)
declare @toolno nvarchar(20)
declare @tooldes nvarchar(MAX)
declare @toollife float
select @oldID = inserted.SL_NO , @type = inserted.[Type] , @material = inserted.Material , @matdes = inserted.Material_Description , @toolno = inserted.Tool_Code , @tooldes = inserted.Tool_Description
, @toollife = inserted.Tool_Life
from inserted
insert into PINQC.dbo.Tool_Management_History(Old_Table_ID , Old_Type , New_Type , Old_Material , New_Material , Old_Material_Description , New_Material_Description , Old_Tool_Code , New_Tool_Code ,
Old_Tool_Description , New_Tool_Description , Old_Tool_Life , New_Tool_Life , Changed_By , Changed_At , Change_Type)
values(@oldID , [Tool Management].[Type] , @type , [Tool Management].Material , @material , [Tool Management].Material_Description , @matdes , [Tool Management].Tool_Code , @toolno ,
[Tool Management].Tool_Description , @tooldes , [Tool Management].Tool_Life , @toollife , CURRENT_USER , GETDATE() , 'Inserted')
END
这是执行触发器时的错误消息(我知道我不能像这样从 [工具管理] 调用值,但我不知道其他方法)
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Type" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Material" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Material_Description" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Code" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 19 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Description" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 19 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Life" could not be bound.
您的触发器使 a classic mistake: 未考虑 inserted
table.[=19 中的多个(或零个)行=]
通常,您应该将 INSERT
UPDATE
和 DELETE
触发器合二为一。但这是一个非常简单的触发器,因此您可以通过对 inserted
和 deleted
table 进行完全连接来组合它们。您应该通过主键加入,我假设是 SL_NO
CREATE OR ALTER TRIGGER ToolHistory on [Tool Management]
AFTER INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON;
INSERT PINQC.dbo.Tool_Management_History
(Old_Table_ID, Old_Type, New_Type, Old_Material, New_Material,
Old_Material_Description, New_Material_Description, Old_Tool_Code, New_Tool_Code,
Old_Tool_Description, New_Tool_Description, Old_Tool_Life, New_Tool_Life,
Changed_By, Changed_At, Change_Type)
SELECT
ISNULL(i.SL_NO, d.SL_NO),
d.[Type],
i.[Type],
d.Material,
i.Material,
d.Material_Description,
i.Material_Description,
d.Tool_Code,
i.Tool_Code,
d.Tool_Description,
i.Tool_Description,
d.Tool_Life,
i.Tool_Life,
CURRENT_USER,
GETDATE(),
CASE WHEN d.SL_NO IS NULL THEN 'Inserted' WHEN d.SL_NO IS NULL THEN 'Deleted' ELSE 'Update' END
FROM inserted i
FULL JOIN deleted d ON d.SL_NO = i.SL_NO;
GO
我是 MSSQL 的新手,为了跟踪 sql table 中的更改,我创建了一个单独的 table 并在发生任何更改时填充它,我在下面写了这个触发器(目前我正在为插入而写,因此旧值和新值可能看起来很愚蠢,但我需要相同的东西,而任何东西都得到更新)我打算在此之后再写两个用于删除和更新的触发器。 以下是触发代码,但我无法获取旧值,请帮助我:
create trigger ToolHistory_Insert on [Tool Management]
after Insert
as
begin
set nocount on;
declare @oldID int
declare @type nvarchar(20)
declare @material float
declare @matdes nvarchar(MAX)
declare @toolno nvarchar(20)
declare @tooldes nvarchar(MAX)
declare @toollife float
select @oldID = inserted.SL_NO , @type = inserted.[Type] , @material = inserted.Material , @matdes = inserted.Material_Description , @toolno = inserted.Tool_Code , @tooldes = inserted.Tool_Description
, @toollife = inserted.Tool_Life
from inserted
insert into PINQC.dbo.Tool_Management_History(Old_Table_ID , Old_Type , New_Type , Old_Material , New_Material , Old_Material_Description , New_Material_Description , Old_Tool_Code , New_Tool_Code ,
Old_Tool_Description , New_Tool_Description , Old_Tool_Life , New_Tool_Life , Changed_By , Changed_At , Change_Type)
values(@oldID , [Tool Management].[Type] , @type , [Tool Management].Material , @material , [Tool Management].Material_Description , @matdes , [Tool Management].Tool_Code , @toolno ,
[Tool Management].Tool_Description , @tooldes , [Tool Management].Tool_Life , @toollife , CURRENT_USER , GETDATE() , 'Inserted')
END
这是执行触发器时的错误消息(我知道我不能像这样从 [工具管理] 调用值,但我不知道其他方法)
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Type" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Material" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Material_Description" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 18 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Code" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 19 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Description" could not be bound.
Msg 4104, Level 16, State 1, Procedure ToolHistory_Insert, Line 19 [Batch Start Line 0]
The multi-part identifier "Tool Management.Tool_Life" could not be bound.
您的触发器使 a classic mistake: 未考虑 inserted
table.[=19 中的多个(或零个)行=]
通常,您应该将 INSERT
UPDATE
和 DELETE
触发器合二为一。但这是一个非常简单的触发器,因此您可以通过对 inserted
和 deleted
table 进行完全连接来组合它们。您应该通过主键加入,我假设是 SL_NO
CREATE OR ALTER TRIGGER ToolHistory on [Tool Management]
AFTER INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON;
INSERT PINQC.dbo.Tool_Management_History
(Old_Table_ID, Old_Type, New_Type, Old_Material, New_Material,
Old_Material_Description, New_Material_Description, Old_Tool_Code, New_Tool_Code,
Old_Tool_Description, New_Tool_Description, Old_Tool_Life, New_Tool_Life,
Changed_By, Changed_At, Change_Type)
SELECT
ISNULL(i.SL_NO, d.SL_NO),
d.[Type],
i.[Type],
d.Material,
i.Material,
d.Material_Description,
i.Material_Description,
d.Tool_Code,
i.Tool_Code,
d.Tool_Description,
i.Tool_Description,
d.Tool_Life,
i.Tool_Life,
CURRENT_USER,
GETDATE(),
CASE WHEN d.SL_NO IS NULL THEN 'Inserted' WHEN d.SL_NO IS NULL THEN 'Deleted' ELSE 'Update' END
FROM inserted i
FULL JOIN deleted d ON d.SL_NO = i.SL_NO;
GO