【发布时间】:2019-11-11 10:31:13
【问题描述】:
我创建了以下数据库、表和更新触发器以维护更新日志。当用户修改 name/salary/gender/departmentid 时,它会更新 'tblEmployeeAudit' 表中的日志。
现在有一个问题,如果我们只是更新系统中已经更新的相同值,那么 'tblEmployeeAudit' 表中不应该更新更新条目。
例如:- 如果 tblEmployee 的 EmployeeName Ravi 具有 Id=1 则如果更新相同的名称,则不应更新日志,但在此不会发生。请帮帮我。
Create database learning
use learning
USE [learning]
GO
/****** Object: Table [dbo].[tblEmployee] Script Date: 11/11/2019 3:54:13 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblEmployee](
[Id] [int] NOT NULL,
[Name] [nvarchar](30) NULL,
[Salary] [int] NULL,
[Gender] [nvarchar](10) NULL,
[DepartmentId] [int] NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [learning]
GO
/****** Object: Table [dbo].[tblEmployeeAudit] Script Date: 11/11/2019 3:54:34 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblEmployeeAudit](
[Id] [int] IDENTITY(1,1) NOT NULL,
[AuditData] [nvarchar](1000) NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Alter trigger tr_tblEmployee_ForUpdate
on tblEmployee
For Update
As
Begin
Declare @Id int
Declare @OldName nvarchar(30),@NewName nvarchar(30)
Declare @OldSalary int,@NewSalary int
Declare @OldGender nvarchar(10),@NewGender nvarchar(10)
Declare @OldDeptId int,@NewDeptId int
Declare @AuditString nvarchar(1000)
Select * into #TempTable
from inserted
While(Exists(Select Id from #TempTable))
Begin
Set @AuditString=''
Select Top 1 @Id=Id,@NewName=Name,@NewSalary=Salary,@NewGender=Gender,@NewDeptId=DepartmentId from #TempTable
Select @OldName=Name,@OldSalary=Salary,@OldGender=Gender,@OldDeptId=DepartmentId from deleted where Id=@Id
Set @AuditString='Employee with Id='+CAST(@Id as nvarchar(4))+' changed '
if(@OldName<>@NewName)
Set @AuditString=@AuditString+'NAME from '+@OldName+' to '+@NewName
if(@OldSalary<>@NewSalary)
Set @AuditString=@AuditString+'Salary from '+@OldSalary+' to '+@NewSalary
if(@OldGender<>@NewGender)
Set @AuditString=@AuditString+'Gender from '+@OldGender+' to '+@NewGender
if(@OldDeptId<>@NewDeptId)
Set @AuditString=@AuditString+'DepartmentId from '+@OldDeptId+' to '+@NewDeptId
insert into tblEmployeeAudit values(@AuditString)
Delete from #TempTable where Id=@Id
End
End
update tblEmployee
set Name='Joseph' where Id=4
注意:- 即使没有不匹配的行更新,也跟随插入的数据 Id=4 的员工已更改
【问题讨论】:
-
您使用的是什么版本的 SQL Server?如果是 2016 年或更高版本,您可能应该检查 system-versioned-tables 而不是为此使用触发器。
-
主要原因是以下查询导致插入默认行,如果执行任何更新查询。 Set @AuditString='Employee with Id='+CAST(@Id as nvarchar(4))+' changed '
-
我使用的是SQL server 2014版本,我相信版本不会影响这个
-
只需要检查新旧值是否不匹配,然后再将记录插入 tblEmployeeAudit,如果是,则将记录插入 tblEmployeeAudit 否则无操作
标签: sql-server tsql database-trigger