如何分析,更新行时发生的事情

时间:2016-04-28 04:38:35

标签: mysql sql audit-logging

我有一张这样的表:

| id |   address   |  name  |    oid    | state | event_id | ctrl |
-------------------------------------------------------------------
| 1  | test_addr_1 | test_1 | 25.345.17 |   1   |     0    |  15  |

我需要在行中更新数据时获取event_id。

我想做这样的事情:

如果新名称与旧名称event_id = event_id + 1不相等 如果新的oid与旧的event_id = event_id + 2不相等 如果新状态不等于旧状态event_id = event_id + 4
如果新ctrl大于旧ctrl event_id = event_id + 8

# Params to procedure
PROCEDURE Write(IN pAddr VARCHAR(20), IN pName VARCHAR(20), IN pOid VARCHAR(20), IN pState TINYINT, IN pCtrl INT)

#procedure body
SET @ev = 0;
SELECT
CASE
    WHEN name != pName THEN SET @ev = @ev + 1
    WHEN oid != pOid THEN SET @ev = @ev + 2
    WHEN state != pState THEN SET @ev = @ev + 4
    WHEN ctrl > pCtrl THEN SET @ev = @ev + 8
END 
FROM table1 

UPDATE table1 SET ..... , event_id = @ev WHERE address = pAddr

我该怎么办?或者最好不要在SQL的帮助下制作它?

2 个答案:

答案 0 :(得分:0)

如前所述,此处可以使用audit trigger来确保捕获来自所有来源的更改。但是,我建议进行两项修改:

1)审计表 - 使用其他表来保存审计数据,因为这些表往往会增长,不建议在同一结构中混合操作和审计数据(即使在同一个数据库中) )

2)使用更友好的更改标志 - 从您的示例中,您似乎在整数值中设置位。虽然这提供了紧凑的数据(在单个整数内捕获许多变化),但它需要更复杂的操作来查看名称何时更改。审计表可以只包含nameChangedoidChanged等BIT(1)列。

CREATE TRIGGER table1Audit BEFORE UPDATE ON <table1>
FOR EACH ROW BEGIN
    SET @ev = 
        (CASE WHEN OLD.name != NEW.name THEN 1 ELSE 0 END) + 
        (CASE WHEN OLD.oid != NEW.oid THEN 2 ELSE 0 END) + 
        (CASE WHEN OLD.state != NEW.state THEN 4 ELSE 0 END) +  
        (CASE WHEN OLD.ctrl != NEW.ctrl THEN 8 ELSE 0 END)

    -- INSERT INTO someaudittable
    --'table1', @ev
END;

答案 1 :(得分:0)

解决!感谢@Alexei。 我想知道为什么这行被添加到历史表中。

结果是:

CREATE TRIGGER SetReason BEFORE UPDATE ON <table1>
FOR EACH ROW BEGIN
    SET NEW.event_id = 
        (CASE WHEN OLD.name != NEW.name THEN 1 ELSE 0 END) + 
        (CASE WHEN OLD.oid != NEW.oid THEN 2 ELSE 0 END) + 
        (CASE WHEN OLD.state != NEW.state THEN 4 ELSE 0 END) +  
        (CASE WHEN OLD.ctrl != NEW.ctrl THEN 8 ELSE 0 END)    
END;