Utworzenie triggera bazy danych z poziomu aplikacji - kłopot

0

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

zapewne klasa, którą wykonujesz zapytania nie zezwala na kilka zapytań na raz

1 użytkowników online, w tym zalogowanych: 0, gości: 1