トリガーからストアドプロシージャを呼び出します
-
16-10-2019 - |
質問
次の構文を使用して、MySQLにストアドプロシージャを作成しました。
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 ;
参考までに、ストアドプロシージャを大幅に簡素化しましたが、問題なく機能することは知っています。
私ができることをしたいのは、このように機能するusergroup_commentsからトリガーを設定することです。
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;
しかし、何らかの理由で、MySQLは私にエラーをスローします。これは、4行目に構文エラーがあることを示すのに役立ちません。
MySQLドキュメントを調べて、トリガーの制限に関する情報を見つけましたが、かなり複雑であることがわかりました。
http://dev.mysql.com/doc/refman/5.1/en/stored-program-restrictions.html
どんなアイデアも役に立ちます。
解決 2
ですから、これは数時間私を信じているかどうかを悩ませた問題であることがわかりました。
sp_set-comment_countという手順を簡単に定義できます。ただし、上記の手順を呼び出すと、同じように機能しません。
sp_set -comment_countを呼び出します(これは、サーバーがマイナスとして解釈されるためであると仮定することしかできません)。
その後、ストアドプロシージャ名を変更してアンダースコアのみを使用して変更しましたが、すべてを解決したようです。
他のヒント
トリガー内からストアドプロシージャを呼び出すべきではない大きな理由があります。
トリガーは、本質的に、ストアドプロシージャです。彼らの行動は、ロールバックするのが事実上難しいです. 。基礎となるすべてのテーブルがINNODBであっても、比例したボリュームの共有行ロックと、排他的な行ロックからの迷惑な断続性が発生します。トリガーがテーブルを操作していた場合はそうです ヘビーデューティを実行するために停滞している挿入と更新 MVCC 各呼び出し内でトリガーへ.
トリガーがオーバーヘッドが必要であることを忘れないでください。実際、によれば MySQLストアドプロシージャプログラミング, 、ページ256ヘッド「トリガーオーバーヘッド」の下で次のように述べています。
必然的に、トリガーが適用されるDMLステートメントにオーバーヘッドを追加することを覚えておくことが重要です。実際のオーバーヘッドの量はトリガーの性質に依存しますが、すべてのMySQLトリガーが各行に対して実行されるように---オーバーヘッドは、多数の行を処理するステートメントのために急速に蓄積する可能性があります。したがって、トリガーに高価なSQLステートメントまたは手続きコードを配置しないでください。
トリガーオーバーヘッドの拡張された説明は、529〜531ページに記載されています。そのセクションからの結論のポイントは、次のように述べています。
ここでのレッスンは次のとおりです。トリガーコードは、DMLステートメントの影響を受けるすべての行に対して1回実行されるため、トリガーはDMLパフォーマンスの最も重要な要因になります。トリガー本体内のコードは、可能な限り軽量である必要があります。特に、トリガー内のSQLステートメントは、可能な限りインデックスによってサポートされる必要があります。
まとめ
私は...するだろう トリガーからストアドプロシージャを呼び出さないことを強くお勧めします, 、MySQLが許可していても。 mysql 5.5の現在の制限をチェックする必要があります.
構文エラーについて言った場合、デリミッターを変更するのを忘れてしまう可能性が最も高い(ストアドプロシージャのために行ったように)。だからあなたは必要です
DELIMITER $$
CREATE TRIGGER `usergroups_comments_insert` AFTER INSERT ON `usergroups_comment`
FOR EACH ROW
BEGIN
CALL sp_set_count(NEW.`gid`);
END;
$$
後のコンマのように見えます AC
構文エラーです:
UPDATE usergroups
SET allCount = AC,
WHERE ........