it-swarm.com.de

Rufen Sie eine gespeicherte Prozedur von einem Trigger aus auf

Ich habe eine gespeicherte Prozedur in MySQL mit der folgenden Syntax erstellt.

DROP PROCEDURE IF EXISTS `sp-set_comment_count`;

DELIMITER $$

CREATE PROCEDURE `sp_set-comment_count` (IN _id INT)
BEGIN
   -- AC   - AllCount
   DECLARE AC INT DEFAULT 0;

   SELECT COUNT(*) AS ac
     INTO AC
     FROM usergroups AS ug
LEFT JOIN usergroup_comments AS ugm ON ugm.`gid` = ug.`id`
LEFT JOIN mediagallery AS dm ON ugm.mid = dm.`id`
    WHERE dm.`status` NOT IN (200, 201, 202, 203, 204, 205)
      AND ug.`id` = _id;

   UPDATE usergroups
      SET allCount = AC,
    WHERE usergroups.`id` = _id;

END $$
DELIMITER ;

Zu Ihrer Information Ich habe die gespeicherte Prozedur stark vereinfacht, aber ich weiß, dass sie ohne Probleme funktioniert.

Ich möchte in der Lage sein, einen Auslöser von usergroup_comments einzurichten, der so funktioniert.

DROP TRIGGER IF EXISTS `usergroups_comments_insert` 

CREATE TRIGGER `usergroups_comments_insert` AFTER INSERT ON `usergroups_comment`
    FOR EACH ROW
    BEGIN
       CALL sp-set-comment_count(NEW.`gid`);
    END;

Aber aus irgendeinem Grund wirft jedes Mal, wenn ich MySQL mache, einen Fehler auf mich, der weniger hilfreich ist, als dass in Zeile 4 ein Syntaxfehler vorliegt.

Ich habe die MySQL-Dokumentation durchgesehen und einige Informationen zu Einschränkungen von Triggern gefunden, aber festgestellt, dass sie ziemlich kompliziert sind.

http://dev.mysql.com/doc/refman/5.1/en/stored-program-restrictions.html

Irgendwelche Ideen wären hilfreich.

17
Mark D

Es stellt sich also heraus, dass dies das Problem ist, das mich einige Stunden lang geplagt hat, ob Sie es glauben oder nicht.

Ich kann leicht eine Prozedur mit dem Namen sp_set-comment_count definieren. Wenn Sie diese Prozedur aufrufen, funktioniert sie jedoch nicht auf die gleiche Weise.

CALL sp_set-comment_count (Ich kann nur annehmen, dass dies daran liegt, dass der Server das - als Minus interpretiert).

Ich habe seitdem den Namen der gespeicherten Prozedur geändert, um nur Unterstriche zu verwenden, und es scheint alles gelöst zu haben.

8
Mark D

Es gibt gute Gründe, warum Sie gespeicherte Prozeduren niemals aus Triggern heraus aufrufen sollten.

Trigger sind von Natur aus gespeicherte Prozeduren. Ihre Aktionen sind praktisch schwer rückgängig zu machen. . Selbst wenn alle zugrunde liegenden Tabellen InnoDB sind, tritt ein proportionales Volumen an gemeinsam genutzten Zeilensperren und eine störende Unterbrechung durch exklusive Zeilensperren auf. Dies wäre der Fall, wenn Trigger Tabellen manipulieren würden, wobei INSERTs und UPDATEs stagnieren würden, um schwere Aufgaben auszuführen MVCC in jedem Aufruf zu einem Auslöser .

Vergessen Sie nicht, dass Trigger Overhead erfordern. Laut MySQL Stored Procedure Programming sagt Seite 256 unter der Überschrift "Trigger Overhead" Folgendes aus:

Es ist wichtig zu beachten, dass Trigger der DML-Anweisung, für die sie gelten, notwendigerweise zusätzlichen Aufwand hinzufügen. Der tatsächliche Overhead hängt von der Art des Triggers ab. Da jedoch alle MySQL-Trigger FÜR JEDE REIHE ausgeführt werden, kann sich der Overhead für Anweisungen, die eine große Anzahl von Zeilen verarbeiten, schnell ansammeln. Sie sollten daher vermeiden, teure SQL-Anweisungen oder Prozedurcode in Trigger zu setzen.

Eine erweiterte Erläuterung des Trigger-Overheads finden Sie auf den Seiten 529-531. Der abschließende Punkt aus diesem Abschnitt lautet wie folgt:

Die Lektion hier lautet: Da der Triggercode für jede von einer DML-Anweisung betroffene Zeile einmal ausgeführt wird, kann der Trigger leicht zum wichtigsten Faktor für die DML-Leistung werden. Code im Trigger-Body muss so leicht wie möglich sein, und insbesondere sollten alle SQL-Anweisungen im Trigger nach Möglichkeit von Indizes unterstützt werden.

Ich habe in einem früheren Beitrag andere böse Aspekte von Triggern erklärt.

[~ # ~] Zusammenfassung [~ # ~]

Ich würde dringend empfehlen, keine gespeicherten Prozeduren von einem Trigger aufzurufen, selbst wenn MySQL dies zulässt. Sie sollten die aktuellen Einschränkungen für MySQL 5.5 überprüfen .

24
RolandoMySQLDBA

Wenn es sich um einen Syntaxfehler handelt, haben Sie höchstwahrscheinlich vergessen, das Trennzeichen zu ändern (wie bei der gespeicherten Prozedur). Deswegen brauchst du

DELIMITER $$
CREATE TRIGGER `usergroups_comments_insert` AFTER INSERT ON `usergroups_comment`
FOR EACH ROW
BEGIN
   CALL sp_set_count(NEW.`gid`);
END;
$$
5
a1ex07

Das Komma nach AC ist ein Syntaxfehler:

UPDATE usergroups
   SET allCount = AC,
 WHERE ........
1
user22800