it-swarm.it

Chiamare una procedura memorizzata da un trigger

Ho creato una procedura memorizzata in mysql usando la sintassi seguente.

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 ;

Cordiali saluti Ho semplificato notevolmente la procedura memorizzata, ma so che funziona senza problemi.

Quello che mi piacerebbe poter fare è impostare un trigger da usergroup_comments che funzioni in questo modo.

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;

Ma per qualche motivo ogni volta che lo faccio mysql mi lancia un errore che è poco utile affermando che c'è un errore di sintassi nella riga 4.

Ho esaminato la documentazione di mysql e ho trovato alcune informazioni sulle restrizioni dei trigger, ma l'ho trovato abbastanza contorto.

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

Qualsiasi idea sarebbe utile.

17
Mark D

Quindi si scopre che questo è il problema che mi ha afflitto per qualche ora, che ci crediate o no.

Posso facilmente definire una procedura chiamata sp_set-comment_count. Tuttavia, quando si chiama detta procedura, non funziona allo stesso modo.

CALL sp_set-comment_count (posso solo supporre che ciò sia dovuto al fatto che il server interpreta il - come meno).

Da allora ho cambiato il nome della procedura memorizzata per usare solo caratteri di sottolineatura e sembra aver risolto tutto.

8
Mark D

C'è un ottimo motivo per cui non dovresti mai chiamare le procedure memorizzate dai trigger.

I trigger sono, per natura, procedure memorizzate. Le loro azioni sono praticamente difficili da ripristinare . Anche se tutte le tabelle sottostanti sono InnoDB, si verificherà un volume proporzionale di blocchi di riga condivisi e fastidiose intermittenze da blocchi di riga esclusivi. Questo sarebbe il caso se i trigger manipolassero le tabelle con INSERT e AGGIORNAMENTI stagnati per eseguire operazioni pesanti MVCC all'interno di ogni chiamata a un trigger .

Non dimenticare che i trigger richiedono overhead. Infatti, secondo MySQL Stored Procedure Programming , pagina 256 sotto il titolo "Trigger Overhead" dice quanto segue:

È importante ricordare che, per necessità, i trigger generano un sovraccarico dell'istruzione DML a cui si applicano. la quantità effettiva di overhead dipenderà dalla natura del trigger, ma --- poiché tutti i trigger MySQL vengono eseguiti PER OGNI FILA --- l'overhead può accumularsi rapidamente per le istruzioni che elaborano un numero elevato di righe. Dovresti quindi evitare di inserire costose istruzioni SQL o codici procedurali nei trigger.

Una spiegazione estesa del sovraccarico del trigger è riportata alle pagine 529-531. Il punto conclusivo di quella sezione afferma quanto segue:

La lezione qui è questa: poiché il codice trigger verrà eseguito una volta per ogni riga interessata da un'istruzione DML, il trigger può facilmente diventare il fattore più significativo nelle prestazioni DML. Il codice all'interno del corpo del trigger deve essere il più leggero possibile e, in particolare, qualsiasi istruzione SQL nel trigger deve essere supportata da indici ogni volta che è possibile.

Ho spiegato altri aspetti negativi di Trigger in un post precedente.

[~ ~ #] Riassunto [~ ~ #]

Consiglierei di non chiamare alcuna procedura memorizzata da un trigger , anche se MySQL lo consente. Dovresti dare un'occhiata alle attuali restrizioni per MySQL 5.5 .

24
RolandoMySQLDBA

Se dice di errore di sintassi, molto probabilmente ti sei dimenticato di cambiare delimitatore (come hai fatto per la procedura memorizzata). Quindi hai bisogno

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

Sembra che la virgola dopo AC sia un errore di sintassi:

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