Hm.. pewnie jest to prosta sprawa (a przynajmniej mam taką nadzieje), ale mam problem z utworzeniem triggera z poziomu aplikacji (dodam od razu, że robię to przy pomocy c++/Qt).
Przygotowywany trigger jest "składany w locie" (zmienna dotycząca tabeli..) i początkowo chciałem to zrobić z poziomu bazy danych (mysql), ale doczytałem, że jest to niemożliwe poniweaż prepared statements nie wspiera takiej mozliwości..
Z tego powodu pozostało mi to z poziomu apki, ale przy próbie dostaje syntax error..
Jak to wygląda "od środka"..
Trigger 'oryginalnie' wyglądał tak (patrz Listing 1. na samym końcu posta..),
po uproszczeniu (usunąłem nowe linie) wygląda to tak:
#Listing 2.
DROP TRIGGER IF EXISTS `tr_bi_strzaly`; #nowa linia
DELIMITER $$ #nowa linia
CREATE TRIGGER `tr_bi_strzaly` BEFORE INSERT ON `strzaly`FOR EACH ROW BEGIN UPDATE wyniki SET ilosc_punktow=ilosc_punktow+NEW.wynik WHERE id_wynik=NEW.id_wyniki; IF NEW.wynik >= 10 THEN UPDATE wyniki SET ilosc_10=ilosc_10+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 9 AND 10 THEN UPDATE wyniki SET ilosc_9=ilosc_9+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 8 AND 9 THEN UPDATE wyniki SET ilosc_8=ilosc_8+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 7 AND 8 THEN UPDATE wyniki SET ilosc_7=ilosc_7+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 6 AND 7 THEN UPDATE wyniki SET ilosc_6=ilosc_6+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 5 AND 6 THEN UPDATE wyniki SET ilosc_5=ilosc_5+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 4 AND 5 THEN UPDATE wyniki SET ilosc_4=ilosc_4+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 3 AND 4 THEN UPDATE wyniki SET ilosc_3=ilosc_3+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 2 AND 3 THEN UPDATE wyniki SET ilosc_2=ilosc_2+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 1 AND 2 THEN UPDATE wyniki SET ilosc_1=ilosc_1+1 WHERE id_wynik=NEW.id_wyniki; ELSE IF NEW.wynik BETWEEN 0 AND 1 THEN UPDATE wyniki SET ilosc_0=ilosc_0+1 WHERE id_wynik=NEW.id_wyniki;END IF; END IF; END IF; END IF; END IF; END IF; END IF; END IF; END IF; END IF;END IF;
END $$ #nowa linia
gdzie zauważyłem, że tylko takie zapytanie wykonywane bezpośrednio na bazie danych (mysql workbench) przechodzi.. muszą być nowe linie w tych miejscach gdzie napisałem.. Kierując się tym przygotowałem tego typu zapytanie w c++/Qt:
QString tableResult = "wyniki"+ctID;
QString tableShot = "strzaly"+ctID;
QString triggerName = "wstawStrzlay"+ctID;
QString Query = QString("DROP TRIGGER IF EXISTS "+triggerName+"; ") +
QString("\n") +
QString("DELIMITER $$ ") +
QString("\n") +
QString("CREATE TRIGGER "+triggerName+" BEFORE INSERT ON "+tableShot+" ") +
QString("FOR EACH ROW BEGIN ") +
QString("UPDATE "+tableResult+" SET ilosc_punktow=ilosc_punktow+NEW.wynik WHERE id_wyniki=NEW.id_wyniki; ") +
QString("if NEW.wynik >= 10 then ") +
QString("UPDATE "+tableResult+" SET ilosc_10=ilosc_10+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 9 and 10 then ") +
QString("UPDATE "+tableResult+" SET ilosc_9=ilosc_9+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 8 and 9 then ") +
QString("UPDATE "+tableResult+" SET ilosc_8=ilosc_8+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 7 and 8 then ") +
QString("UPDATE "+tableResult+" SET ilosc_7=ilosc_7+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 6 and 7 then ") +
QString("UPDATE "+tableResult+" SET ilosc_6=ilosc_6+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 5 and 6 then ") +
QString("UPDATE "+tableResult+" SET ilosc_5=ilosc_5+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 4 and 5 then ") +
QString("UPDATE "+tableResult+" SET ilosc_4=ilosc_4+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 3 and 4 then ") +
QString("UPDATE "+tableResult+" SET ilosc_3=ilosc_3+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 2 and 3 then ") +
QString("UPDATE "+tableResult+" SET ilosc_2=ilosc_2+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 1 and 2 then ") +
QString("UPDATE "+tableResult+" SET ilosc_1=ilosc_1+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("else ") +
QString("if NEW.wynik between 0 and 1 then ") +
QString("UPDATE "+tableResult+" SET ilosc_0=ilosc_0+1 WHERE id_wyniki=NEW.id_wyniki; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("end if; ") +
QString("\n") +
QString("END $$ ") ;
natomiast wywołuje to poprzez prostą konstrukcje:
QSqlQuery Query;
Query.exec(Query);
Wnioski/obserwacje..
Wywołując powyższe zapytanie nie otrzymuje błędu, ale też nie zostaje dodany trigger...
Natomiast wywołując to zapytanie bez pierwszych dwóch linii QString("DROP TRIGGER IF EXISTS "+triggerName+"; ") + QString("\n") + (bo w sumie trigger jest zakładany dla nowo-utworzonej tabeli..) dostaje syntax error wyglądający tak: (w sumie nie wiedząc czemu on w ogóle występuje..)
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$ CREATE TRIGGER insertShot_ct_24 BEFORE INSERT ON shot_ct_24 FOR E' at line 1 QMYSQL: Unable to execute query"
Podsumowując..
Co robię nie tak ? (miał ktoś okazje robić trigger z poziomu aplikacji ? )
------------------------------------------
#Listing 1.
DROP TRIGGER IF EXISTS `tr_bi_strzaly`;
DELIMITER $$
CREATE TRIGGER `tr_bi_strzaly` BEFORE INSERT ON `strzaly`
FOR EACH ROW BEGIN
UPDATE wyniki SET ilosc_punktow=ilosc_punktow+NEW.wynik WHERE id_wynik=NEW.id_wyniki;
IF NEW.wynik >= 10 THEN
UPDATE wyniki SET ilosc_10=ilosc_10+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 9 AND 10 THEN
UPDATE wyniki SET ilosc_9=ilosc_9+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 8 AND 9 THEN
UPDATE wyniki SET ilosc_8=ilosc_8+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 7 AND 8 THEN
UPDATE wyniki SET ilosc_7=ilosc_7+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 6 AND 7 THEN
UPDATE wyniki SET ilosc_6=ilosc_6+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 5 AND 6 THEN
UPDATE wyniki SET ilosc_5=ilosc_5+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 4 AND 5 THEN
UPDATE wyniki SET ilosc_4=ilosc_4+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 3 AND 4 THEN
UPDATE wyniki SET ilosc_3=ilosc_3+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 2 AND 3 THEN
UPDATE wyniki SET ilosc_2=ilosc_2+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 1 AND 2 THEN
UPDATE wyniki SET ilosc_1=ilosc_1+1 WHERE id_wynik=NEW.id_wyniki;
ELSE
IF NEW.wynik BETWEEN 0 AND 1 THEN
UPDATE wyniki SET ilosc_0=ilosc_0+1 WHERE id_wynik=NEW.id_wyniki;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END IF;
END $$
DELIMITER ;