2012-05-03 18 views
0

私の考えは、次の列を持っていた「changelog_table」と呼ばれるテーブルを持っていることでした。mySQLでは、あるテーブルが他のすべてのテーブルから変更ログを保持するように、どのようにトリガーを作成しますか?

updated_table  //the table being updated 
updated_column //the column being updated 
updated_row  //the id of the row being updated 
updated_content //this is what they updated the field to 
updated_user  //the user who updated 
updated_datetime //the timestamp it was updated 

私はこれは私が本当にしたいと思いますが、私は間違っているかもしれないものの最小値と最大値の両方だと思います。 また、私は数週間の読書の後、変数を格納する方法(「どのテーブルが更新されているか」、「どの列が更新されているか」など)を私のトリガーで理解できません。

「foo_table」という表があり、列「bar_column」と行「58008」があり、ユーザー「peter_griffin」によって「this is the new content」に更新されているとします。正午12/30/2013

どのようなトリガーは、そのような外観をキャプチャできますか?

答えて

2

UPDATEの各テーブルに別々のトリガーを作成する必要があります(必要に応じてINSERTDELETEもあります)。彼らはそれぞれ、実際のロギングを行うのと同じストアドプロシージャを呼び出すことができます。

トリガは、操作が実行されているテーブルの名前を含むパラメータをストアドプロシージャに渡すことができます(トリガはテーブル固有であるため、これはわかります。ハードコードする必要があります)。どの列が更新されたかを検出するには、それぞれのトリガー内で、NEW.columnOLD.columnをそれぞれの表の各列に対して比較する必要があります。例えば

CREATE TRIGGER upd_tbl_name AFTER UPDATE ON tbl_name FOR EACH ROW 
    CALL AuditLog('UPDATE', 'tbl_name', NEW.id, CONCAT_WS(',', 
    IF(NEW.columnA <=> OLD.columnA, NULL, CONCAT('columnA:=', NEW.columnA)), 
    IF(NEW.columnB <=> OLD.columnB, NULL, CONCAT('columnB:=', NEW.columnB)), 
    -- etc. 
)); 

CREATE PROCEDURE AuditLog(
    Action VARCHAR(10), 
    TableName VARCHAR(64), 
    RowID INT, 
    Columns TEXT, 
) 
    INSERT INTO changelog_table VALUES (
    Action, 
    TableName, 
    RowID, 
    Columns 
    USER(), 
    NOW(), 
); 
+0

OOoooh、私はそれをトリガーすると、各テーブルごとにupdate_tableにトリガーを必要ですか? (もしそうなら、私はこれについてむしろ間違っていると思う) –

+0

@JerryRowe:はい、そうです。スケルトンの例は上記に含まれています。 – eggyal

関連する問題