2016-04-28 7 views
2

ich eine Tabelle wie folgt aus:Wie zu analysieren, was passiert während der Aktualisierung Zeilen

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

Ich brauche in Reihe zu bekommen event_id während Aktualisierungsdaten.

mag ich so etwas wie dies zu tun:

Wenn neuer Name entspricht nicht mit alten Namen event_id = event_id + 1
Wenn neue oid nicht mit alten oid gleich event_id = event_id + 2
Wenn neuer Zustand nicht mit altem Zustand entspricht event_id = event_id + 4
Wenn neue Abfrage größer dann alt 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 

Wie kann ich es tun? Oder wird es besser sein, es nicht mit Hilfe von SQL zu machen?

+0

Es klingt für mich wie ein Trigger nach dem Update wäre eine bessere Wahl hier. Übrigens, können Sie sicher sein, dass mehrere Ihrer Bedingungen nicht gleichzeitig ausgelöst werden? –

Antwort

0

gelöst! Danke an @Alexei. Ich wollte wissen, warum die Zeile zur History-Tabelle hinzugefügt wurde.

Das Ergebnis ist:

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; 
0

Wie bereits vorgeschlagen, kann hier ein audit trigger verwendet werden, um sicherzustellen, dass Änderungen von allen Quellen erfasst werden. Allerdings schlage ich zwei Änderungen:

1) Audit-Tabellen - andere Tabellen verwenden, um Audit-Daten zu halten, da diese Tabellen neigen dazu, zu wachsen und es ist nicht betriebsbereit und Audit-Daten zu mischen in den gleichen Strukturen empfohlen (auch in die gleiche Datenbank)

2) Verwenden Sie mehr freundliche Änderung Flagge - von Ihrem Beispiel scheint es, dass Sie Bits in einem ganzzahligen Wert setzen. Während dies kompakte Daten bereitstellt (viele Änderungen innerhalb einer einzelnen Ganzzahl abfangen), erfordert es mehr verschachtelte Operationen, um zu sehen, wann sich der Name zum Beispiel geändert hat. Die Audit-Tabelle kann einfach BIT (1) Spalten wie nameChanged haben, oidChanged usw.

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; 
+0

Danke! Es war hilfreich für mich. Ich muss wissen, was passiert ist, wenn Werte anders sind. Die Idee ist: wenn ev == 1 (Objekt wurde umbenannt), wenn ev == 4 (Objekt kann Arbeit sein), wenn ev == 12 (Objekt war nicht arbeiten) und etc. Update event_id und fügen Sie diese Zeile in die History-Tabelle . Ist es möglich, evenend_it in der gleichen Tabelle zu aktualisieren? – txid

Verwandte Themen