Tsql 需要比较两行中的差异吗?

Tsql 需要比较两行中的差异吗?,tsql,stored-procedures,iteration,Tsql,Stored Procedures,Iteration,我需要将两行相互比较,然后将更改后的字段写入表中 我的桌子: CREATE TABLE dbo.tUserChanges ( cID int IDENTITY (1,1), cChangeDate DateTime, cValueChanged varchar(30), cPreviousValue bit, cCurrentValue bit ) 在我的C程序中,当对用户进行更改时,需要更新用户表 这是通过存储过程完成的: CREATE PROCEDURE [dbo].[UUser]

我需要将两行相互比较,然后将更改后的字段写入表中

我的桌子:

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表中有更多的值,但为了保持排序,我删除了一些值

所以我需要做的是在更新tUsers表之前创建一个temp表,以便在更新完成后比较这两行,然后将发生的更改更正到新表中

我已经尝试过这个方法,但我知道有更好的方法,而且它也不能提供所需的结果:

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
我不确定我是否需要在这里使用光标,或者我可以做些什么来获得结果?
任何帮助都将不胜感激。

最好使用FOR UPDATE触发器

创建触发器,这是一种特殊的存储过程 当用户尝试指定的操作时自动执行 指定表上的数据修改语句。Microsoft®SQL 服务器™ 允许为任何给定插入创建多个触发器, 更新或删除语句

编辑

使用动态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

SQL不会神奇地将字符串或变量解释为名称。如果您从tUsers中选择@ColumnName,其中UID=@UID,您的意思是选择@ColumnName变量的值,而不是从表中检索名为@ColumnName的列是的,我知道这一点,但我将其作为示例发布,因为我不知道该怎么做,所以我必须对表中的所有字段进行更新。在我看来,表中有216个字段,您有两个选择。1.复制/粘贴insert语句216次,更改列。2.使用动态sql。在这种情况下,我对这两种解决方案的感觉都很复杂。正确地复制/粘贴要容易得多,但是动态SQL较短,向基表添加列会自动覆盖。您将如何执行动态SQLoption@user1171437-我添加了一个可能的示例,但请确保对其进行广泛测试。我还没有验证这种构造是否可以在更新触发器中实现。非常感谢您的帮助,我非常感谢
  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