SQL Server动态字符串不起作用

时间:2017-01-30 08:27:32

标签: sql sql-server tsql

我想在Audit表中创建一个字符串,用于对数据进行的任何修改。我创建了这个更新触发器,一切正常,除了我的字符串根据更新的字符被分成不同的条目。像这样:

  

8 ID = 1的员工将DepartmentID从1更改为4

  9 ID = 1的员工将FIRSTNAME从Sam更改为Matt

相反,我需要在一个长字符串中汇总所有更新。像这样:

  

8 ID = 1的员工将DepartmentID从1更改为4 FIRSTNAME从Sam更改为Matt

有人能弄明白我的代码有什么问题吗?

ALTER TRIGGER [dbo].[tr_tblEmployee_ForUpdate]
ON [dbo].[tblEmployee]
FOR UPDATE
AS
BEGIN
    DECLARE @ID INT
    DECLARE @OldFName NVARCHAR(20), @NewFName NVARCHAR(20)
    DECLARE @OldLName NVARCHAR(20), @NewLName NVARCHAR(20)
    DECLARE @OldDOB DATETIME, @NewDOB DATETIME
    DECLARE @OldCity NVARCHAR (20), @NewCity NVARCHAR (20)
    DECLARE @OldSalary INT, @NewSalary INT
    DECLARE @OldGender NVARCHAR(20), @NewGender NVARCHAR(20)
    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, @NewFName = First_Name, @NewLName = Last_Name, 
        @NewDOB = DateOfBirth, @NewCity = City, @NewSalary = Salary,
        @NewGender = Gender, @NewDeptID = DepartmentID
        FROM #TempTable

        SELECT @OldFName = First_Name, @OldLName = Last_Name, 
        @OldDOB = DateOfBirth, @OldCity = City, @OldSalary = Salary,
        @OldGender = Gender, @OldDeptID = DepartmentID
        FROM deleted WHERE ID = @ID

        SET @AuditString = 'Employee with ID = ' + CAST(@ID AS NVARCHAR (4)) + ' changed'
        IF(@OldFName <> @NewFName)
            SET @AuditString = @AuditString + ' FIRSTNAME from ' + @OldFName + ' to ' + @NewFName

        IF(@OldLName <> @NewLName)
            SET @AuditString = @AuditString + ' LASTNAME from ' + @OldLName + ' to ' + @NewLName

        IF(@OldDOB <> @NewDOB)
            SET @AuditString = @AuditString + ' DOB from ' + CAST(@OldDOB AS NVARCHAR(100)) + ' to ' + CAST(@NewDOB AS NVARCHAR(100))

        IF(@OldCity <> @NewCity)
            SET @AuditString = @AuditString + ' CITY from ' + @OldCity + ' to ' + @NewCity

        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 ' + CAST(@OldDeptID AS NVARCHAR(5)) + ' to ' + CAST(@NewDeptID AS NVARCHAR(5))

        INSERT INTO tblAudit VALUES (@AuditString)

        DELETE FROM #TempTable WHERE ID = @ID
    END
END

1 个答案:

答案 0 :(得分:1)

我必须承认,我无法理解为什么您的触发器会为每个更改的列插入一行。

但是,我会尝试使用基于集合的方法重写触发器,而不是逐行执行。

类似的东西:

INSERT INTO tblAudit
SELECT 'Employee with ID = ' + CAST(@ID AS NVARCHAR (4)) + ' changed '
        + CASE WHEN deleted.First_Name == deleted.First_Name THEN '' ELSE ' DOB from ' + CAST(deleted.DOB AS NVARCHAR(100)) + ' to ' + CAST(inserted.DOB AS NVARCHAR(100)) END
        + CASE WHEN deleted.City == inserted.City THEN '' ELSE ' CITY from ' + deleted.City + ' to ' + inserted.City END 
        + CASE WHEN deleted.Salary == inserted.Salary THEN '' ELSE ' SALARY from ' + deleted.Salary + ' to ' + inserted.Salary END
        + CASE WHEN deleted.Gender == inserted.Gender THEN '' ELSE ' GENDER from ' + deleted.Gender + ' to ' + inserted.Gender END
        + CASE WHEN deleted.DeptID == inserted.DeptID THEN '' ELSE ' DepartmentID from ' + CAST(deleted.DeptID AS NVARCHAR(5)) + ' to ' + CAST(inserted.DeptID AS NVARCHAR(5)) END
FROM Inserted LEFT JOIN Deleted ON Inserted.Id = Deleted.Id