z jakiegoś powodu, na maszynie MySQL 5.5.30, wyzwalacz, który usuwa wiersz z drugim stole nie ma już ognia usuwania spust na drugim stole.MySQL 05.05.30 kaskadowo wyzwalacze nie działa
Działa to doskonale na naszej lokalnej wersji MySQL 5.5.25
Nie mogę znaleźć żadnej dokumentacji, która by wyjaśnić ten problem, ma ktoś może mieć równe problem?
Jest to albo błąd, który występuje w wersji MySQL większa niż 5.5.25 lub „cecha”, która jest włączona przypadkowo.
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 tutaj powielać moich kroków:
Database
CREATE DATABASE "triggerTest" DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Stoły
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;
wyzwalacze
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 ;
Q: Dlaczego zacytować identyfikatorów używając cudzysłowia? (Zamiast backticks)
Bo mi się nie podoba "niszowych składni"
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)
Test-obudowy 1: Oczekiwane zachowanie (wersja bazy danych 5.2.20)
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.5.20 |
+-----------+
1 row in set (0.00 sec)
mysql> SET GLOBAL general_log := ON;
badania wkładka wyzwalania
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"
oczekiwane zawartość tabeli:
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)
badania zmiana wyzwalania, zestaw aktywny
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"
oczekiwane zawartość tabeli:
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)
testowanie aktualizacji spust, zestaw nieaktywna
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"
oczekiwane zawartość tabeli:
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: nieoczekiwane zachowanie (MySQL w wersji 5.5.30)
Święty wyzwala grml - Wiesz co? Szkoda, że nie testowałem drugi przypadek pierwszy - niestety nie udało mi się odtworzyć ten błąd .. test pracował na 5.5.30, a także będzie na bieżąco informować :)
EDIT wyzwalania nie kaskadowo z powodu nieznanego definiującego, który pozostał w zrzucie sql wykonanym dla produkcji. Usunięcie DEFINER = w zrzutach wyzwalaczy (alternatywnym rozwiązaniem byłoby utworzenie użytkownika lub zmiana DEFINER = na istniejący) rozwiązał problem, rozwiązał część problemu.
Nieznany definiujący nie powoduje żadnych wyjściowe pliku dziennika
* pokaż rzeczywisty fragment kodu *, proszę. – Sebas
Coś interesującego w dziennikach? Czy możesz stworzyć mały przykład na zupełnie nowej bazie danych, aby zilustrować problem? (Jeśli jest odtwarzalny, łatwiej go zrozumieć, imo). – halfer
Hej, Michel, tak, jak powiedział Halfer, możesz podać przykład wzoru twojego stołu. – medina