Per qualche motivo, su una macchina MySQL 5.5.30, un trigger che cancella una riga da una seconda tabella non attiva più il trigger di cancellazione nella seconda tabella.I trigger a cascata MySQL 5.5.30 non funzionano
Questo funziona perfettamente sul nostro locale versione di MySQL 5.5.25
Non ho trovato alcuna documentazione che potrebbe spiegare questo comportamento, non qualcuno forse ha un problema di parità?
Questo è un errore che si verifica nella versione di MySQL superiore a 5.5.25 o una "funzione" abilitata accidentalmente.
UPDATE table1 => fires BEFORE UPDATE trigger ON table1
table1 BEFORE UPDATE TRIGGER executes: DELETE FROM table2 => should fire BEFORE DELETE trigger on table2 (but doesn't)
table 2 BEFORE DELETE TRIGGER executes: DELETE FROM table3 (never happens)
OK qui il mio riprodurre passaggi:
database
CREATE DATABASE "triggerTest" DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Tavoli
CREATE TABLE "table1" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"active" tinyint(1) NOT NULL DEFAULT '0',
"sampleData" varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY ("id")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
CREATE TABLE "table2" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"table1_id" int(11) NOT NULL DEFAULT '0',
PRIMARY KEY ("id"),
CONSTRAINT "test2_fk_table1_id" FOREIGN KEY ("table1_id") REFERENCES "table1" ("id") ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
CREATE TABLE "table3" (
"id" int(11) NOT NULL AUTO_INCREMENT,
"table1_id" int(11) NOT NULL DEFAULT '0',
PRIMARY KEY ("id"),
CONSTRAINT "test3_fk_table1_id" FOREIGN KEY ("table1_id") REFERENCES "table1" ("id") ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;
Trigger
DELIMITER $$
CREATE TRIGGER "table1_rtrg_AI" AFTER INSERT ON "table1" FOR EACH ROW
BEGIN
IF NEW."active" THEN
INSERT INTO "table2" ("table1_id") SELECT NEW."id";
END IF;
END$$
CREATE TRIGGER "table1_rtrg_BU" BEFORE UPDATE ON "table1" FOR EACH ROW
BEGIN
IF NOT NEW."active" AND OLD."active" THEN
DELETE FROM "table2" WHERE "table1_id" = OLD."id";
END IF;
IF NEW."active" AND NOT OLD."active" THEN
INSERT INTO "table2" ("table1_id") SELECT NEW."id";
END IF;
END$$
CREATE TRIGGER "table2_rtrg_AI" AFTER INSERT ON "table2" FOR EACH ROW
BEGIN
INSERT INTO "table3" ("table1_id") SELECT NEW."table1_id";
END$$
CREATE TRIGGER "table2_rtrg_BD" BEFORE DELETE ON "table2" FOR EACH ROW
BEGIN
DELETE FROM "table3" WHERE "table1_id" = OLD."table1_id";
END$$
DELIMITER ;
D: Perché si cita identificatori utilizzando virgolette? (Invece di backticks)
Perché non mi piace "sintassi di nicchia"
mysql> show variables LIKE 'sql_mode';
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode | PIPES_AS_CONCAT,**ANSI_QUOTES**,IGNORE_SPACE,NO_UNSIGNED_SUBTRACTION,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
Testcase 1: Comportamento previsto (database della versione 5.2.20)
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.20 |
+-----------+
1 row in set (0.00 sec)
mysql> SET GLOBAL general_log := ON;
test inserto grilletto
mysql> INSERT INTO "table1" ("active", "sampleData") SELECT 0, 'sample data row 1';
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
general_log:
130423 12:51:27 78010 Query INSERT INTO "table1" ("active", "sampleData") SELECT 0, 'sample data row 1'
mysql> INSERT INTO "table1" ("active", "sampleData") SELECT 1, 'sample data row 2';
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
general_log:
130423 12:51:33 78010 Query INSERT INTO "table1" ("active", "sampleData") SELECT 1, 'sample data row 2'
78010 Query INSERT INTO "table2" ("table1_id") SELECT NEW."id"
78010 Query INSERT INTO "table3" ("table1_id") SELECT NEW."table1_id"
attesi contenuto della tabella:
mysql> SELECT * FROM "table1";
+----+--------+-------------------+
| id | active | sampleData |
+----+--------+-------------------+
| 1 | 0 | sample data row 1 |
| 2 | 1 | sample data row 2 |
+----+--------+-------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM "table2";
+----+-----------+
| id | table1_id |
+----+-----------+
| 1 | 2 |
+----+-----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM "table3";
+----+-----------+
| id | table1_id |
+----+-----------+
| 1 | 2 |
+----+-----------+
1 row in set (0.00 sec)
test segnale di avvio, dell'insieme attivo
mysql> UPDATE "table1" SET "active" = 1 WHERE "id" = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
query_log:
130423 12:52:15 78010 Query UPDATE "table1" SET "active" = 1 WHERE "id" = 1
78010 Query INSERT INTO "table2" ("table1_id") SELECT NEW."id"
78010 Query INSERT INTO "table3" ("table1_id") SELECT NEW."table1_id"
contenuto della tabella attesi:
mysql> SELECT * FROM "table1";
+----+--------+-------------------+
| id | active | sampleData |
+----+--------+-------------------+
| 1 | 1 | sample data row 1 |
| 2 | 1 | sample data row 2 |
+----+--------+-------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM "table2";
+----+-----------+
| id | table1_id |
+----+-----------+
| 2 | 1 |
| 1 | 2 |
+----+-----------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM "table3";
+----+-----------+
| id | table1_id |
+----+-----------+
| 2 | 1 |
| 1 | 2 |
+----+-----------+
2 rows in set (0.00 sec)
test segnale di avvio, impostare inattivo
mysql> UPDATE "table1" SET "active" = 0 WHERE "id" = 2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
query_log:
130423 12:52:49 78010 Query UPDATE "table1" SET "active" = 0 WHERE "id" = 2
78010 Query DELETE FROM "table2" WHERE "table1_id" = NEW."id"
78010 Query DELETE FROM "table3" WHERE "table1_id" = OLD."table1_id"
attesi contenuto della tabella:
mysql> SELECT * FROM "table1";
+----+--------+-------------------+
| id | active | sampleData |
+----+--------+-------------------+
| 1 | 1 | sample data row 1 |
| 2 | 0 | sample data row 2 |
+----+--------+-------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM "table2";
+----+-----------+
| id | table1_id |
+----+-----------+
| 2 | 1 |
+----+-----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM "table3";
+----+-----------+
| id | table1_id |
+----+-----------+
| 2 | 1 |
+----+-----------+
1 row in set (0.00 sec)
Testcase2: comportamento imprevisto (MySQL versione 5.5.30)
Santo innesca grml - Sai una cosa? Peccato che non ho la prova secondo caso prima - purtroppo non era in grado di riprodurre l'errore .. il test ha lavorato 5.5.30 pure, vi terremo aggiornati :)
EDIT trigger non ha cascata a causa di un definitore sconosciuto che era rimasto nella discarica sql creata per la produzione. Rimozione DEFINER = nei dump di trigger (soluzione alternativa sarebbe quella di creare l'utente o di cambiare DEFINER = ad uno esistente) risolto il problema, risolto una parte del problema.
Il definitore sconosciuto non ha causato alcun output file di log
* mostra il codice effettivo *, per favore. – Sebas
Qualcosa di interessante nei registri? Inoltre, puoi creare un piccolo esempio su un nuovo database per illustrare il problema? (Se è replicabile, è più facile da capire, imo). – halfer
Hey Michel, sì, come detto halfer potresti darci un esempio del design del tuo tavolo. – medina