所以我试图为我的表创建一个更新触发器。触发器成功创建,没有问题。但是当我尝试更新我的桌子时,它给了我一个错误说"已经有一个名为' #TritTable'在数据库"。我不明白为什么更新查询在成功创建触发器时会出现此错误?
以下是使用临时表的触发器的代码:
Alter trigger tr_tblPerson_forUpdate
on tblPerson
for Update
as
Begin
Declare @Id int
Declare @OldName nvarchar(20), @NewName nvarchar(20)
Declare @OldEmail nvarchar(20), @NewEmail nvarchar(20)
Declare @OldGenderId int, @NewGenderId int
Declare @OldAge int, @NewAge int
Declare @OldSalary int, @NewSalary int
Declare @OldCity nvarchar(20), @NewCity nvarchar(20)
Declare @Auditstring nvarchar (max)
while(Exists(Select Id from inserted))
Begin
Select * into #TempTable from INSERTED -- Since the logical tables INSERTED & DELETED cannot be
-- modified manually, we have to create a separate temptable
-- ourselves and store everything from INSERTED table in that
-- table and then use that to form a loop
Set @Auditstring = ''
Select Top 1 @Id = Id, @NewName = Name, @NewEmail = Email, -- from the inserted table which contains the new data, we are
@NewGenderId = GenderId, @NewAge = Age, @NewSalary = Salary, -- pulling the new data and assigning it to our new data
@NewCity = City from #TempTable -- holding variables
Select @OldName = Name, @OldEmail = Email, @OldGenderId = GenderId,
@OldAge = Age, @OldSalary = Salary,
@OldCity = City from DELETED where Id = @Id
Set @Auditstring = 'Person with ID = ' + cast(@Id as nvarchar(5)) + 'changed'
if(@NewName!=@OldName)
Set @Auditstring = 'Name to ' + @NewName + ','
if(@NewEmail!=@OldEmail)
Set @Auditstring = 'Email to ' + @NewEmail + ','
if(@NewGenderId!=@OldGenderId)
Set @Auditstring = 'Gender to ' + cast(@NewGenderId as nvarchar(5))+ ','
if(@NewAge!=@OldAge)
Set @Auditstring = 'Age to ' + cast(@NewAge as nvarchar(5))+ ','
if(@NewSalary!=@OldSalary)
Set @Auditstring = 'Salary to ' + cast(@NewSalary as nvarchar(20)) + ','
if(@NewCity!=@OldCity)
Set @Auditstring = 'City to ' + @NewCity + 'on ' + cast(GetDate() as nvarchar(20))
insert into tblAudit values (@Auditstring)
Delete from #TempTable where ID = @Id
End
End
以下是提供错误的更新查询:
update tblPerson set Name = 'Ray', Email = 'ray@ray.com', Age = 32, Salary = 3000, City = 'New York'
where ID = 1
答案 0 :(得分:1)
我认为触发器的整个主体应该是:
INSERT INTO tblAudit (/* Some column name here */)
SELECT
'Person with ID = ' + cast(i.ID as varchar(5)) + ' changed ' +
CASE WHEN i.Name != d.Name THEN 'Name to ' + i.Name + ', ' ELSE '' END +
CASE WHEN i.Email != d.Email THEN 'Email to ' + i.Email + ', ' ELSE '' END +
/* Etc */
FROM
inserted i
inner join
deleted d
on
i.ID = d.ID
这可以处理多行更新而无需循环。不需要临时表。并且审计信息会累积而不是覆盖每个部分