How to create Triggers to add the change events into Audit Log tables

后端 未结 5 1786
悲&欢浪女
悲&欢浪女 2020-12-05 16:33

Suppose we have 50 tables in a database and we want to capture all the changes (Previous value and new value of columns) across the columns of each table. An au

5条回答
  •  伪装坚强ぢ
    2020-12-05 17:09

    This is a little bit improved version of Vlad answer. Audit table has column for 'diff' of changes.

    Auditing rules:

    • INSERT and DELETE - complete record with all fields is stored to audit table
    • UPDATE - only changes on fields is stored

    Audit table structure. diff is column where changes are stored.

    NB: privileges is JSON column on table we are auditing in this case.

    CREATE TABLE roles_audit_log (
        roles_id INT UNSIGNED NOT NULL,
        diff JSON,
        dml_type ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
        dml_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        dml_created_by VARCHAR(255) NOT NULL default 'system',
        PRIMARY KEY (roles_id, dml_type, dml_timestamp)
    );
    

    Trigger for UPDATE statement. Will fill diff column with fields that were changed.

    DELIMITER $$
    
    CREATE TRIGGER roles_audit_au AFTER UPDATE ON `roles` FOR EACH ROW
    BEGIN
        DECLARE m_change text;
        SET m_change = JSON_OBJECT();
    
        IF coalesce(NEW.role, '') != coalesce(OLD.role, '') THEN
            SET m_change = JSON_SET(m_change, '$.role', NEW.role);
        END IF;
    
        IF coalesce(NEW.created_at, '') != coalesce(OLD.created_at, '') THEN
            SET m_change = JSON_SET(m_change, '$.created_at', NEW.created_at);
        END IF;
    
        IF coalesce(NEW.updated_at, '') != coalesce(OLD.updated_at, '') THEN
            SET m_change = JSON_SET(m_change, '$.updated_at', NEW.updated_at);
        END IF;
    
        IF coalesce(NEW.privileges, '') != coalesce(OLD.privileges, '') THEN
            SET m_change = JSON_SET(m_change, '$.privileges', NEW.privileges);
        END IF;
    
        INSERT INTO `roles_audit_log` (
            roles_id,
            diff,
            dml_type,
            dml_created_by
        ) VALUES(
            NEW.id,
            m_change,
            'UPDATE',
            coalesce(@logged_user, 'system')
        );
    END;$$
    DELIMITER ;
    

    Trigger for DELETE statement. Will fill diff with complete row that was deleted.

    DELIMITER $$
    
    CREATE TRIGGER roles_audit_ad AFTER DELETE ON `roles` FOR EACH ROW
    BEGIN
        INSERT INTO `roles_audit_log` (
            roles_id,
            diff,
            dml_type,
            dml_created_by
        ) VALUES(
            OLD.id,
            JSON_OBJECT(
                'id', OLD.id,
                'role', OLD.role,
                'privileges', OLD.privileges,
                'created_at', OLD.created_at,
                'updated_at', OLD.updated_at
            ),
            'DELETE',
            coalesce(@logged_user, 'system')
        );
    END;$$
    DELIMITER ;
    

    Trigger for INSERT statement. Will fill diff with complete row that was deleted.

    DELIMITER $$
    
    CREATE TRIGGER roles_audit_ai AFTER INSERT ON `roles` FOR EACH ROW
    BEGIN
        INSERT INTO `roles_audit_log` (
            roles_id,
            diff,
            dml_type,
            dml_created_by
        ) VALUES(
            NEW.id,
            JSON_OBJECT(
                'id', NEW.id,
                'role', NEW.role,
                'privileges', NEW.privileges,
                'created_at', NEW.created_at,
                'updated_at', NEW.updated_at
            ),
            'INSERT',
            coalesce(@logged_user, 'system')
        );
    END;$$
    DELIMITER ;
    

提交回复
热议问题