2012-02-09 8 views
2

私は2つの行をお互いに比較して、テーブルに変更されたフィールドを書き込む必要があります。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でtempテーブルを作成することです。私はtUsersテーブルを更新して、更新が完了した後に2つの行を比較し、新しいテーブルに加えられた変更を正しく比較できるようにします。

私はこれを試してみましたが、私は良い方法があると知って、それはまた、必要な結果を与えるものではありません:

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

ようなものになるだろう。あなたが 'UID = @ UID'のところでtUsersから@columnNameを選択したところでは、「@ 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を使用して

は、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

私はそれを見て、 2つの選択肢があります。 1. insert文を216回コピー/ペーストし、列を変更します。 2.動的SQLを使用します。この場合、私は**両方の解決策との間に複雑な感情を持っています。コピー/貼り付けの作業ははるかに簡単ですが、動的SQLは短くなり、ベーステーブルへのカラムの追加が自動的に行われます。 –

+0

どのように動的SQLオプションを実行しますか – user1171437

関連する問題