Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wyzwalacz MySQL po aktualizacji tylko w przypadku zmiany wiersza

Jako obejście możesz użyć znacznika czasu (starego i nowego) do sprawdzenia, czy nie aktualizowane, gdy nie ma zmian w wierszu. (Prawdopodobnie jest to źródłem nieporozumień? Ponieważ ten jest również nazywany „w trakcie aktualizacji”, ale nie jest wykonywany, gdy nie nastąpi żadna zmiana) Zmiany w ciągu jednej sekundy nie wykonają tej części wyzwalacza, ale w niektórych przypadkach może to być w porządku (np. gdy masz aplikację, która i tak odrzuca szybkie zmiany).

Na przykład zamiast

IF NEW.a <> OLD.a or NEW.b <> OLD.b /* etc, all the way to NEW.z <> OLD.z */ 
THEN  
  INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ;
END IF

możesz użyć

IF NEW.ts <> OLD.ts 
THEN  
  INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b) ;
END IF

Wtedy nie musisz zmieniać wyzwalacza za każdym razem, gdy aktualizujesz schemat (problem, o którym wspomniałeś w pytaniu).

EDYCJA:Dodano pełny przykład

create table foo (a INT, b INT, ts TIMESTAMP);
create table bar (a INT, b INT);

INSERT INTO foo (a,b) VALUES(1,1);
INSERT INTO foo (a,b) VALUES(2,2);
INSERT INTO foo (a,b) VALUES(3,3);

DELIMITER ///

CREATE TRIGGER ins_sum AFTER UPDATE ON foo
    FOR EACH ROW
    BEGIN
        IF NEW.ts <> OLD.ts THEN  
            INSERT INTO bar (a, b) VALUES(NEW.a, NEW.b);
        END IF;
    END;
///

DELIMITER ;

select * from foo;
+------+------+---------------------+
| a    | b    | ts                  |
+------+------+---------------------+
|    1 |    1 | 2011-06-14 09:29:46 |
|    2 |    2 | 2011-06-14 09:29:46 |
|    3 |    3 | 2011-06-14 09:29:46 |
+------+------+---------------------+
3 rows in set (0.00 sec)

-- UPDATE without change
UPDATE foo SET b = 3 WHERE a = 3;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

-- the timestamo didnt change
select * from foo WHERE a = 3;
+------+------+---------------------+
| a    | b    | ts                  |
+------+------+---------------------+
|    3 |    3 | 2011-06-14 09:29:46 |
+------+------+---------------------+
1 rows in set (0.00 sec)

-- the trigger didn't run
select * from bar;
Empty set (0.00 sec)

-- UPDATE with change
UPDATE foo SET b = 4 WHERE a=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

-- the timestamp changed
select * from foo;
+------+------+---------------------+
| a    | b    | ts                  |
+------+------+---------------------+
|    1 |    1 | 2011-06-14 09:29:46 |
|    2 |    2 | 2011-06-14 09:29:46 |
|    3 |    4 | 2011-06-14 09:34:59 |
+------+------+---------------------+
3 rows in set (0.00 sec)

-- and the trigger ran
select * from bar;
+------+------+---------------------+
| a    | b    | ts                  |
+------+------+---------------------+
|    3 |    4 | 2011-06-14 09:34:59 |
+------+------+---------------------+
1 row in set (0.00 sec)

Działa z powodu zachowania mysql w zakresie obsługi znaczników czasu. Znacznik czasu jest aktualizowany tylko wtedy, gdy nastąpiła zmiana w aktualizacjach.

Dokumentacja jest tutaj:
https://dev .mysql.com/doc/refman/5.7/en/timestamp-initialization.html

desc foo;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| a     | int(11)   | YES  |     | NULL              |                             |
| b     | int(11)   | YES  |     | NULL              |                             |
| ts    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zaawansowane zapytanie MySql:Aktualizuj tabelę informacjami z innej tabeli

  2. Kolejność MySQL według najlepszego dopasowania

  3. Jak obliczyć procent dwóch kolumn w MySQL?

  4. Jak usunąć spacje z ciągu znaków w MySQL?

  5. Funkcja MySQL SIN() — zwraca sinus liczby w MySQL