更新触发器已成功创建,但更新了查询结果错误

时间:2017-05-22 07:36:25

标签: sql sql-server triggers

所以我试图为我的表创建一个更新触发器。触发器成功创建,没有问题。但是当我尝试更新我的桌子时,它给了我一个错误说"已经有一个名为' #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

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

这可以处理多行更新而无需循环。不需要临时表。并且审计信息会累积而不是覆盖每个部分