2012-02-09 52 views
2

我需要将两行相互比较,然后写入更改为表的字段。需要比较两行中的差异吗?

我的表:

CREATE TABLE dbo.tUserChanges 
(
cID int IDENTITY (1,1), 
cChangeDate DateTime, 
cValueChanged varchar(30), 
cPreviousValue bit, 
cCurrentValue bit 
) 

在我的C#程序的用户表需要更改时用户进行的更新。

这是通过存储过程来完成:

CREATE PROCEDURE [dbo].[UUser]  
( 
@User as varchar(15), 
@UCode AS int,  
@UName AS varchar(30),  
@UID AS varchar(10),  
@UPassword AS varchar(15),  
@UPMaintenance as bit,  
@UClient as bit,  
@UFinancial as bit,  
@UViewReceiptImage bit, 
@UViewPayrollData bit 
) 
AS 
BEGIN 
UPDATE tUsers  
SET   
UName = @UName,  
UID = @UID,  
UPassword = @UPassword, UPMaintenance = @UPMaintenance,  
UClient = @UClient,  
UFinancial = @UFinancial, 
UViewReceiptImage = @UViewReceiptImage, 
UViewPayrollData = @UViewPayrollData  
WHERE UCode = @UCode 
END 

有一个在TUSER表,但保持它的目的更值排序我删除了一些值。

所以我需要做的是在befor上创建一个临时表我更新了tUsers表,这样我就可以在更新完成后比较两行,然后对发生在新表中的更改进行比较。

我都试过,但我知道有一个更好的方式,它也没有提供所需的结果:

declare @i int 
set @i = 0 
declare @ColumnCount int 
set @ColumnCount = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = @UID) 
declare @ColumnName varchar(30) 
set @ColumnName = (select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14) 

select UActivateLoan from tusers 

while (@ColumnCount < @i) 
Begin 
    if((select @ColumnName from tUsers where UID = @UID) 
    <> (select @ColumnName from #myTemp where UID = @UID)) 
    Begin 
     Insert into tUserChanges 
     Values(GETDATE(),(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14), 
       (select(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14) from #myTemp where UID = @UID), 
       (select(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14) from tUsers where UID = @UID)) 
    END 
    set @i = @i + 1 
End 

我不知道如果我需要在这里使用游标或者我所能做得到结果? 任何帮助,将不胜感激。

+0

SQL不会奇迹般地解释字符串或变量名。如果你有'从UUID = @UID'的tUsers中选择@ColumnName,你所说的是“选择'@ ColumnName'变量的值,而不是从表格' – 2012-02-09 08:35:01

+0

'中检索名为'@ ColumnName'的列是的,我知道这一点,但我发布了这个例子,因为我不知道如何去做 – user1171437 2012-02-09 09:16:29

回答

2

使用FOR UPDATE触发器会更好。

CREATE TRIGGER dbo.tUser_AfterUpdate ON dbo.tUsers FOR UPDATE AS 
BEGIN 
    IF UPDATE(UName) THEN 
    INSERT INTO tUserChanges 
    SELECT GETDATE() 
      , (SELECT UName FROM DELETED) -- Old Value 
      , (SELECT UName FROM INSERTED) -- New Value 

    ... 
END 

CREATE TRIGGER

Creates a trigger, which is a special kind of stored procedure that executes automatically when a user attempts the specified data-modification statement on the specified table. Microsoft® SQL Server™ allows the creation of multiple triggers for any given INSERT, UPDATE, or DELETE statement.

编辑

使用动态SQL,会像

CREATE TRIGGER dbo.tUser_AfterUpdate ON dbo.tUsers FOR UPDATE AS 
    BEGIN 
    DECLARE @Columns TABLE (name sysname) 
    DECLARE @ColumnName sysname 
    DECLARE @Statement VARCHAR(MAX) 

    INSERT INTO @Columns 
    SELECT name 
    FROM sys.columns 
    WHERE OBJECT_NAME(OBJECT_ID) = 'tUsers' 

    WHILE EXISTS (SELECT * FROM @Columns) 
    BEGIN 
     SELECT TOP 1 @ColumnName = name FROM @Columns 
     DELETE FROM @Columns WHERE name = @ColumnName 

     SET @Statement = 
     'IF UPDATE(' + @ColumnName + ') THEN ' 
     + 'INSERT INTO tUserChanges ' 
     + 'SELECT GETDATE() ' 
     + '  , (SELECT ' + @ColumnName + 'FROM DELETED) -- Old Value' 
     + '  , (SELECT ' + @ColumnName + 'FROM INSERTED) -- New Value' 

     EXEC (@Statement) 
    END 
    END 
+0

然后我必须对表中的所有字段进行更新,表中有216个字段 – user1171437 2012-02-09 09:14:05

+0

正如我所看到的,你有两个选择。 1.复制/粘贴插入语句216次,更改列。 2.使用动态sql。在这种情况下,我对两种**解决方案都有着复杂的感受。正确复制/粘贴的功能要容易得多,但动态SQL更短,并且自动为基表添加列。 – 2012-02-09 09:44:53

+0

您将如何执行动态SQL选项 – user1171437 2012-02-09 09:51:10