2012-02-09 3 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 не магически интерпретирует строки или переменные в качестве имен. Если у вас есть 'select @ColumnName из tUsers, где UID = @ UID', то вы говорите:« выберите значение переменной @ @ ColumnName », а не« получите столбец с именем «@ ColumnName» из таблицы « –

+0

Да, я знаю это, но я разместил это как пример, так как я не уверен, как это сделать. – user1171437

ответ

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

+0

Как я вижу, вы имеют два варианта. 1. Скопируйте/Вставьте инструкцию insert в 216 раз, изменив столбцы. 2. Используйте динамический sql. В этом случае у меня смешанные чувства с ** обоими ** решениями. Гораздо проще получить право на копирование/вставку, но динамический SQL короче и добавление столбцов в базовую таблицу автоматически покрывается. –

+0

Как бы вы сделали динамический вариант SQL – user1171437

Смежные вопросы