<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC</id>
	<title>MySQL - トリガー - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="http://mochiuwiki.e2.valueserver.jp/index.php?action=history&amp;feed=atom&amp;title=MySQL_-_%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC"/>
	<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=MySQL_-_%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC&amp;action=history"/>
	<updated>2026-04-27T10:33:57Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://mochiuwiki.e2.valueserver.jp/index.php?title=MySQL_-_%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC&amp;diff=14292&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == MySQLのトリガー (Trigger) は、テーブルに対する &lt;code&gt;INSERT&lt;/code&gt;、&lt;code&gt;UPDATE&lt;/code&gt;、&lt;code&gt;DELETE&lt;/code&gt; の操作が行われた際に、自動的に実行される特別なストアドプロシージャである。&lt;br&gt; トリガーは、データの整合性チェック、自動値設定、監査ログの記録、集計テーブルの更新等、様々な用途に利用される。&lt;br&gt; &lt;br&gt; トリガーには、&lt;u&gt;BEFOREトリガ…」</title>
		<link rel="alternate" type="text/html" href="http://mochiuwiki.e2.valueserver.jp/index.php?title=MySQL_-_%E3%83%88%E3%83%AA%E3%82%AC%E3%83%BC&amp;diff=14292&amp;oldid=prev"/>
		<updated>2026-02-15T08:46:55Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == MySQLのトリガー (Trigger) は、テーブルに対する &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; の操作が行われた際に、自動的に実行される特別なストアドプロシージャである。&amp;lt;br&amp;gt; トリガーは、データの整合性チェック、自動値設定、監査ログの記録、集計テーブルの更新等、様々な用途に利用される。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; トリガーには、&amp;lt;u&amp;gt;BEFOREトリガ…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
MySQLのトリガー (Trigger) は、テーブルに対する &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; の操作が行われた際に、自動的に実行される特別なストアドプロシージャである。&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーは、データの整合性チェック、自動値設定、監査ログの記録、集計テーブルの更新等、様々な用途に利用される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーには、&amp;lt;u&amp;gt;BEFOREトリガー&amp;lt;/u&amp;gt; と &amp;lt;u&amp;gt;AFTERトリガー&amp;lt;/u&amp;gt; の2種類のタイミングがある。&amp;lt;br&amp;gt;&lt;br /&gt;
* BEFOREトリガー&lt;br /&gt;
*: 行の変更が行われる前に実行され、データの検証や値の変更に使用される。&lt;br /&gt;
* AFTERトリガー&lt;br /&gt;
*: 行の変更が行われた後に実行され、監査ログの記録や集計テーブルの更新に使用される。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;トリガーは、&amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt; の3種類のイベントに対応している。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;各トリガーは、NEW疑似レコード (新しい値) および OLD疑似レコード (変更前の値) を使用して、変更されるデータにアクセスできる。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
MySQLでは、同一テーブル・同一タイミング・同一イベントの複数トリガーが存在する場合、FOLLOWS句とPRECEDES句を使用して実行順序を制御できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーは、FOR EACH ROW (行レベルトリガー) のみをサポートしており、ステートメントレベルトリガーはサポートされていない。&amp;lt;br&amp;gt;&lt;br /&gt;
つまり、影響を受ける各行に対して1回ずつトリガーが実行される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;トリガーにはいくつかの制限事項があり、トリガー内から同じテーブルへの変更操作は不可、トリガー内でのCOMMIT / ROLLBACKは不可などの制約がある。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーの作成 ==&lt;br /&gt;
==== 基本構文 ====&lt;br /&gt;
トリガーを作成するには、&amp;lt;code&amp;gt;CREATE TRIGGER&amp;lt;/code&amp;gt;文を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 CREATE&lt;br /&gt;
    [DEFINER = user]&lt;br /&gt;
    TRIGGER [IF NOT EXISTS] &amp;lt;トリガー名&amp;gt;&lt;br /&gt;
    &amp;lt;トリガータイミング&amp;gt; &amp;lt;トリガーイベント&amp;gt;&lt;br /&gt;
    ON &amp;lt;テーブル名&amp;gt; FOR EACH ROW&lt;br /&gt;
    [&amp;lt;トリガー順序&amp;gt;]&lt;br /&gt;
    &amp;lt;トリガー本体&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 trigger_time: { BEFORE | AFTER }&lt;br /&gt;
 &lt;br /&gt;
 trigger_event: { INSERT | UPDATE | DELETE }&lt;br /&gt;
 &lt;br /&gt;
 trigger_order: { FOLLOWS | PRECEDES } other_trigger_name&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ CREATE TRIGGER文の主要な構成要素&lt;br /&gt;
! 要素 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| DEFINER || トリガーの定義者を指定する。&amp;lt;br&amp;gt;省略した場合は、現在のユーザが定義者になる。&lt;br /&gt;
|-&lt;br /&gt;
| IF NOT EXISTS || トリガーが既に存在する場合にエラーにならず、警告のみが出力される。&amp;lt;br&amp;gt;(MySQL 8.0.29以降)&lt;br /&gt;
|-&lt;br /&gt;
| trigger_name || トリガー名を指定する。&amp;lt;br&amp;gt;データベース内で一意である必要がある。&lt;br /&gt;
|-&lt;br /&gt;
| trigger_time || トリガーの実行タイミングを指定する。&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; または &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| trigger_event || トリガーを起動するイベントを指定する。&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;DELETE&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| tbl_name || トリガーを設定するテーブル名を指定する。&lt;br /&gt;
|-&lt;br /&gt;
| FOR EACH ROW || 行レベルトリガーであることを示す。&amp;lt;br&amp;gt;MySQLでは必須&lt;br /&gt;
|-&lt;br /&gt;
| trigger_order || 同一タイミング・同一イベントの複数トリガーがある場合の実行順序を指定する。&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;FOLLOWS&amp;lt;/code&amp;gt; または &amp;lt;code&amp;gt;PRECEDES&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| trigger_body || トリガーで実行する処理を記述する。&amp;lt;br&amp;gt;複数のSQL文を実行する場合は、BEGINとENDで囲む。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
簡潔なトリガーの例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER users_before_insert&lt;br /&gt;
 BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    SET NEW.created_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;DELIMITER&amp;lt;/code&amp;gt; コマンドは、SQL文の区切り文字を一時的に変更するために使用される。&amp;lt;br&amp;gt;&lt;br /&gt;
トリガー内にセミコロンを含む場合、デフォルトの区切り文字 (セミコロン) では正しく解析されないため、一時的に別の区切り文字 (通常は //) に変更する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== トリガータイミング ====&lt;br /&gt;
トリガータイミングには、BEFOREとAFTERの2種類がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ トリガータイミングの比較&lt;br /&gt;
! タイミング !! 実行タイミング !! 用途 !! NEW.col_nameへの代入&lt;br /&gt;
|-&lt;br /&gt;
| BEFORE || 行の変更が行われる前に実行される || データの検証、値の自動変更 || 可能&lt;br /&gt;
|-&lt;br /&gt;
| AFTER || 行の変更が行われた後に実行される || 監査ログの記録、集計テーブルの更新 || 不可 (読み取り専用)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
BEFOREトリガーでは、&amp;lt;u&amp;gt;SET NEW.col_name = value&amp;lt;/u&amp;gt; の構文を使用して、挿入または更新される値を変更できる。&amp;lt;br&amp;gt;&lt;br /&gt;
AFTERトリガーでは、NEWおよびOLD疑似レコードは読み取り専用であり、値を変更できない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== トリガーイベント ====&lt;br /&gt;
トリガーイベントには、INSERT、UPDATE、DELETEの3種類がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ トリガーイベントとNEW / OLDの使用可否&lt;br /&gt;
! イベント !! 説明 !! NEW !! OLD&lt;br /&gt;
|-&lt;br /&gt;
| INSERT || 新しい行が挿入されるときに実行される || 使用可能 || 使用不可&lt;br /&gt;
|-&lt;br /&gt;
| UPDATE || 行が更新されるときに実行される || 使用可能 || 使用可能&lt;br /&gt;
|-&lt;br /&gt;
| DELETE || 行が削除されるときに実行される || 使用不可 || 使用可能&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* INSERTトリガー&lt;br /&gt;
*: NEWのみが使用可能であり、挿入される新しい値を参照できる。&lt;br /&gt;
* UPDATEトリガー&lt;br /&gt;
*: NEWとOLDの両方が使用可能であり、変更前の値と変更後の値の両方を参照できる。&lt;br /&gt;
* DELETEトリガー&lt;br /&gt;
*: OLDのみが使用可能であり、削除される行の値を参照できる。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== NEWとOLD疑似レコード ====&lt;br /&gt;
トリガー内では、NEWとOLDという特別な疑似レコードを使用して、変更されるデータにアクセスできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ NEWとOLD疑似レコード&lt;br /&gt;
! 疑似レコード !! 説明 !! 使用可能なイベント !! 書き込み可能&lt;br /&gt;
|-&lt;br /&gt;
| NEW.column_name || INSERT / UPDATEで使用する。&amp;lt;br&amp;gt;新しい値を参照する。 || INSERT、UPDATE || BEFOREトリガーのみ可能&lt;br /&gt;
|-&lt;br /&gt;
| OLD.column_name || UPDATE / DELETEで使用する。&amp;lt;br&amp;gt;変更前の値を参照する。 || UPDATE、DELETE || 不可 (読み取り専用)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
BEFOREトリガーでは、&amp;lt;u&amp;gt;SET NEW.col_name = value&amp;lt;/u&amp;gt; の構文を使用して、挿入または更新される値を変更できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
NEWとOLDの使用例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER update_audit BEFORE UPDATE ON products&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- 価格が変更された場合のみ、変更日時を更新&lt;br /&gt;
    IF NEW.price != OLD.price THEN&lt;br /&gt;
       SET NEW.updated_at = NOW();&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーの変更と削除 ==&lt;br /&gt;
MySQLでは、&amp;lt;code&amp;gt;ALTER TRIGGER&amp;lt;/code&amp;gt; 文は存在しない。&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーを変更するには、&amp;lt;code&amp;gt;DROP TRIGGER&amp;lt;/code&amp;gt; 文で削除してから、&amp;lt;code&amp;gt;CREATE TRIGGER&amp;lt;/code&amp;gt; 文で再作成する必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーを削除するには、&amp;lt;code&amp;gt;DROP TRIGGER&amp;lt;/code&amp;gt; 文を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DROP TRIGGER [IF EXISTS] [&amp;lt;スキーマ名&amp;gt;.]&amp;lt;トリガー名&amp;gt;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;IF EXISTS&amp;lt;/code&amp;gt; 句を使用すると、トリガーが存在しない場合でもエラーにならず、警告のみが出力される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* トリガー削除の例&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DROP TRIGGER IF EXISTS users_before_insert;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* スキーマ名を指定してトリガーを削除する例&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DROP TRIGGER IF EXISTS mydb.users_before_insert;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* トリガーを変更するには、削除してから再作成する。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DROP TRIGGER IF EXISTS users_before_insert;&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER users_before_insert&lt;br /&gt;
 BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    SET NEW.email = LOWER(TRIM(NEW.email));&lt;br /&gt;
    SET NEW.created_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーの確認 ==&lt;br /&gt;
トリガーの情報を確認するには、複数の方法がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* トリガー一覧を確認する。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW TRIGGERS [FROM &amp;lt;データベース名&amp;gt;] [LIKE &amp;#039;pattern&amp;#039;];&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* 現在のデータベースのトリガー一覧を表示する例&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW TRIGGERS;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* 特定のデータベースのトリガー一覧を表示する例&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW TRIGGERS FROM mydb;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* パターンマッチングで特定のトリガーを検索する例&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW TRIGGERS LIKE &amp;#039;users%&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* トリガーの定義を確認する。&lt;br /&gt;
*: &amp;lt;code&amp;gt;SHOW CREATE TRIGGER&amp;lt;/code&amp;gt; 文は、トリガーの完全な定義 (CREATE TRIGGER文) を表示する。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW CREATE TRIGGER &amp;lt;トリガー名&amp;gt;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;INFORMATION_SCHEMA.TRIGGERS&amp;lt;/code&amp;gt; テーブルから詳細情報を取得する。&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SELECT TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE,&lt;br /&gt;
        ACTION_STATEMENT, ACTION_TIMING, ACTION_ORDER&lt;br /&gt;
 FROM INFORMATION_SCHEMA.TRIGGERS&lt;br /&gt;
 WHERE TRIGGER_SCHEMA = &amp;#039;&amp;lt;データベース名&amp;gt;&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ INFORMATION_SCHEMA.TRIGGERSテーブルの主要カラム&lt;br /&gt;
! カラム名 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TRIGGER_SCHEMA&amp;lt;/code&amp;gt; || トリガーが定義されているデータベース名&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TRIGGER_NAME&amp;lt;/code&amp;gt; || トリガー名&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EVENT_MANIPULATION&amp;lt;/code&amp;gt; || トリガーイベント (INSERT、UPDATE、DELETE)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EVENT_OBJECT_SCHEMA&amp;lt;/code&amp;gt; || トリガーが設定されているテーブルのデータベース名&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EVENT_OBJECT_TABLE&amp;lt;/code&amp;gt; || トリガーが設定されているテーブル名&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ACTION_ORDER&amp;lt;/code&amp;gt; || 同一タイミング・同一イベントの複数トリガーがある場合の実行順序&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ACTION_STATEMENT&amp;lt;/code&amp;gt; || トリガーで実行される処理の内容&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;ACTION_TIMING&amp;lt;/code&amp;gt; || トリガーのタイミング (BEFORE、AFTER)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CREATED&amp;lt;/code&amp;gt; || トリガーの作成日時&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
特定のテーブルに設定されているトリガーを確認する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SELECT TRIGGER_NAME, ACTION_TIMING, EVENT_MANIPULATION, ACTION_ORDER&lt;br /&gt;
 FROM INFORMATION_SCHEMA.TRIGGERS&lt;br /&gt;
 WHERE EVENT_OBJECT_SCHEMA = &amp;#039;mydb&amp;#039;&lt;br /&gt;
   AND EVENT_OBJECT_TABLE = &amp;#039;users&amp;#039;&lt;br /&gt;
 ORDER BY ACTION_TIMING, EVENT_MANIPULATION, ACTION_ORDER;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーの順序 ==&lt;br /&gt;
==== FOLLOWS句 と PRECEDES句 ====&lt;br /&gt;
MySQL 5.7以降では、同一テーブル・同一タイミング・同一イベントの複数トリガーが存在する場合、FOLLOWS句とPRECEDES句を使用して実行順序を制御できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ FOLLOWS句とPRECEDES句&lt;br /&gt;
! 構文 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| FOLLOWS other_trigger&lt;br /&gt;
| 指定したトリガー (other_trigger) の後に実行される&lt;br /&gt;
|-&lt;br /&gt;
| PRECEDES other_trigger&lt;br /&gt;
| 指定したトリガー (other_trigger) の前に実行される&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;FOLLOWS句とPRECEDES句を指定しない場合、最後に作成されたトリガーが最初に実行される (後入れ先出し) 動作になる。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーの実行順序を制御する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 -- 最初のトリガー&lt;br /&gt;
 CREATE TRIGGER users_before_insert_1&lt;br /&gt;
 BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    SET NEW.email = LOWER(TRIM(NEW.email));&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 -- 2番目のトリガー (users_before_insert_1の後に実行)&lt;br /&gt;
 CREATE TRIGGER users_before_insert_2&lt;br /&gt;
 BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 FOLLOWS users_before_insert_1&lt;br /&gt;
 BEGIN&lt;br /&gt;
    SET NEW.created_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 -- 3番目のトリガー (users_before_insert_2の前に実行)&lt;br /&gt;
 CREATE TRIGGER users_before_insert_3&lt;br /&gt;
 BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 PRECEDES users_before_insert_2&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- 検証処理&lt;br /&gt;
    IF NEW.age &amp;lt; 0 OR NEW.age &amp;gt; 150 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Age must be between 0 and 150&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
上記の例では、トリガーの実行順序は以下のようになる。&amp;lt;br&amp;gt;&lt;br /&gt;
# &amp;lt;u&amp;gt;users_before_insert_1&amp;lt;/u&amp;gt; (最初)&lt;br /&gt;
# &amp;lt;u&amp;gt;users_before_insert_3&amp;lt;/u&amp;gt; (users_before_insert_2の前)&lt;br /&gt;
# &amp;lt;u&amp;gt;users_before_insert_2&amp;lt;/u&amp;gt; (users_before_insert_1の後)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ACTION_ORDER&amp;lt;/code&amp;gt; カラムで実行順序を確認できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SELECT TRIGGER_NAME, ACTION_TIMING, EVENT_MANIPULATION, ACTION_ORDER&lt;br /&gt;
 FROM INFORMATION_SCHEMA.TRIGGERS&lt;br /&gt;
 WHERE EVENT_OBJECT_TABLE = &amp;#039;users&amp;#039;&lt;br /&gt;
   AND ACTION_TIMING = &amp;#039;BEFORE&amp;#039;&lt;br /&gt;
   AND EVENT_MANIPULATION = &amp;#039;INSERT&amp;#039;&lt;br /&gt;
 ORDER BY ACTION_ORDER;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ACTION_ORDER&amp;lt;/code&amp;gt; カラムの値は、実行順序を示す数値である。&amp;lt;br&amp;gt;&lt;br /&gt;
値が小さいほど、先に実行される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== BEFOREトリガーとAFTERトリガーの使い分け ==&lt;br /&gt;
BEFOREトリガーとAFTERトリガーは、用途に応じて使い分ける必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ BEFOREトリガーとAFTERトリガーの使い分け&lt;br /&gt;
! タイミング !! 主な用途 !! 特徴&lt;br /&gt;
|-&lt;br /&gt;
| BEFORE&lt;br /&gt;
|&lt;br /&gt;
* データの検証&lt;br /&gt;
* 値の自動変更 / 正規化&lt;br /&gt;
* デフォルト値の設定&lt;br /&gt;
* 制約のチェック&lt;br /&gt;
|&lt;br /&gt;
* &amp;lt;code&amp;gt;SET NEW.col_name = value&amp;lt;/code&amp;gt;で値を変更可能&lt;br /&gt;
* エラーを発生させることで操作を中断可能&lt;br /&gt;
|-&lt;br /&gt;
| AFTER&lt;br /&gt;
|&lt;br /&gt;
* 監査ログの記録&lt;br /&gt;
* 集計テーブルの更新&lt;br /&gt;
* 他のテーブルへのデータ連携&lt;br /&gt;
* 通知の送信&lt;br /&gt;
|&lt;br /&gt;
* NEW / OLDは読み取り専用&lt;br /&gt;
* データ変更後の処理に適している&lt;br /&gt;
* 他のテーブルへの書き込みが可能&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
BEFOREトリガーは、データが実際にテーブルに書き込まれる前に実行されるため、データの検証や値の変更に適している。&amp;lt;br&amp;gt;&lt;br /&gt;
BEFOREトリガー内でSIGNAL文を使用してエラーを発生させることで、操作を中断できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
AFTERトリガーは、データが既にテーブルに書き込まれた後に実行されるため、監査ログの記録や集計テーブルの更新に適している。&amp;lt;br&amp;gt;&lt;br /&gt;
AFTERトリガーでは、NEW / OLD疑似レコードは読み取り専用であり、値を変更できない。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
BEFOREトリガーで操作を中断する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER validate_age BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    IF NEW.age &amp;lt; 0 OR NEW.age &amp;gt; 150 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Age must be between 0 and 150&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&amp;lt;/u&amp;gt; は、ユーザー定義例外の汎用コードであり、エラーを発生させて操作を中断する。&amp;lt;br&amp;gt;&lt;br /&gt;
MESSAGE_TEXTには、エラーメッセージを指定する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== サンプルクエリ ==&lt;br /&gt;
==== データ検証 ====&lt;br /&gt;
BEFOREトリガーを使用して、データの妥当性を検証する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
以下の例では、年齢が0未満または150を超える場合にエラーを発生させ、INSERT操作を中断する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER validate_age BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    IF NEW.age &amp;lt; 0 OR NEW.age &amp;gt; 150 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Age must be between 0 and 150&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
複数の条件を検証する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER validate_product BEFORE INSERT ON products&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- 価格の検証&lt;br /&gt;
    IF NEW.price &amp;lt;= 0 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Price must be greater than 0&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
 &lt;br /&gt;
    -- 在庫数の検証&lt;br /&gt;
    IF NEW.stock &amp;lt; 0 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Stock cannot be negative&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
&lt;br /&gt;
    -- 商品コードの検証&lt;br /&gt;
    IF LENGTH(NEW.product_code) != 8 THEN&lt;br /&gt;
       SIGNAL SQLSTATE &amp;#039;45000&amp;#039;&lt;br /&gt;
          SET MESSAGE_TEXT = &amp;#039;Product code must be 8 characters&amp;#039;;&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 自動値設定 ====&lt;br /&gt;
BEFOREトリガーを使用して、値を自動的に設定または正規化する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER users_before_insert BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- メールアドレスを小文字に変換し、前後の空白を削除&lt;br /&gt;
    SET NEW.email = LOWER(TRIM(NEW.email));&lt;br /&gt;
 &lt;br /&gt;
    -- 作成日時を自動設定&lt;br /&gt;
    SET NEW.created_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATEトリガーで更新日時を自動設定する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER users_before_update BEFORE UPDATE ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    SET NEW.updated_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
条件付きで値を自動設定する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER products_before_update BEFORE UPDATE ON products&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- 価格が変更された場合のみ、価格変更日時を更新&lt;br /&gt;
    IF NEW.price != OLD.price THEN&lt;br /&gt;
       SET NEW.price_updated_at = NOW();&lt;br /&gt;
    END IF;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 監査ログの記録 ====&lt;br /&gt;
AFTERトリガーを使用して、データ変更の監査ログを記録する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
まず、監査ログ用のテーブルを作成する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 CREATE TABLE audit_log (&lt;br /&gt;
    log_id INT AUTO_INCREMENT PRIMARY KEY,&lt;br /&gt;
    table_name VARCHAR(100),&lt;br /&gt;
    action VARCHAR(10),&lt;br /&gt;
    old_values TEXT,&lt;br /&gt;
    new_values TEXT,&lt;br /&gt;
    changed_by VARCHAR(100),&lt;br /&gt;
    changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP&lt;br /&gt;
 );&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
UPDATEトリガーで変更履歴を記録する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER audit_update AFTER UPDATE ON employees&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    INSERT INTO audit_log (table_name, action, old_values, new_values, changed_by)&lt;br /&gt;
    VALUES (&amp;#039;employees&amp;#039;, &amp;#039;UPDATE&amp;#039;,&lt;br /&gt;
       CONCAT(&amp;#039;name=&amp;#039;, OLD.name, &amp;#039;,salary=&amp;#039;, OLD.salary),&lt;br /&gt;
       CONCAT(&amp;#039;name=&amp;#039;, NEW.name, &amp;#039;,salary=&amp;#039;, NEW.salary),&lt;br /&gt;
       USER());&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;USER()&amp;lt;/code&amp;gt; 関数は、現在接続しているユーザ名を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
INSERTとDELETEの監査ログを記録する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER audit_insert AFTER INSERT ON employees&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    INSERT INTO audit_log (table_name, action, new_values, changed_by)&lt;br /&gt;
    VALUES (&amp;#039;employees&amp;#039;, &amp;#039;INSERT&amp;#039;,&lt;br /&gt;
       CONCAT(&amp;#039;id=&amp;#039;, NEW.id, &amp;#039;,name=&amp;#039;, NEW.name, &amp;#039;,salary=&amp;#039;, NEW.salary),&lt;br /&gt;
       USER());&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER audit_delete AFTER DELETE ON employees&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    INSERT INTO audit_log (table_name, action, old_values, changed_by)&lt;br /&gt;
    VALUES (&amp;#039;employees&amp;#039;, &amp;#039;DELETE&amp;#039;,&lt;br /&gt;
       CONCAT(&amp;#039;id=&amp;#039;, OLD.id, &amp;#039;,name=&amp;#039;, OLD.name, &amp;#039;,salary=&amp;#039;, OLD.salary),&lt;br /&gt;
       USER());&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 集計テーブルの更新 ====&lt;br /&gt;
AFTERトリガーを使用して、集計テーブルを自動的に更新する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
注文テーブルと注文明細テーブルがあり、注文明細が挿入されたときに注文の合計金額を自動更新する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 CREATE TABLE orders (&lt;br /&gt;
    id INT PRIMARY KEY,&lt;br /&gt;
    customer_id INT,&lt;br /&gt;
    total_amount DECIMAL(10,2) DEFAULT 0.00&lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 CREATE TABLE order_items (&lt;br /&gt;
    id INT PRIMARY KEY,&lt;br /&gt;
    order_id INT,&lt;br /&gt;
    product_id INT,&lt;br /&gt;
    quantity INT,&lt;br /&gt;
    price DECIMAL(10,2),&lt;br /&gt;
    FOREIGN KEY (order_id) REFERENCES orders(id)&lt;br /&gt;
 );&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
注文明細が挿入されたときに、注文の合計金額を更新するトリガーを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER update_order_total AFTER INSERT ON order_items&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    UPDATE orders&lt;br /&gt;
    SET total_amount = (&lt;br /&gt;
       SELECT SUM(quantity * price)&lt;br /&gt;
       FROM order_items&lt;br /&gt;
       WHERE order_id = NEW.order_id&lt;br /&gt;
    )&lt;br /&gt;
    WHERE id = NEW.order_id;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
注文明細が更新または削除された時にも、合計金額を更新するトリガーを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER update_order_total_on_update AFTER UPDATE ON order_items&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    UPDATE orders&lt;br /&gt;
    SET total_amount = (&lt;br /&gt;
       SELECT SUM(quantity * price)&lt;br /&gt;
       FROM order_items&lt;br /&gt;
       WHERE order_id = NEW.order_id&lt;br /&gt;
    )&lt;br /&gt;
    WHERE id = NEW.order_id;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER update_order_total_on_delete AFTER DELETE ON order_items&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    UPDATE orders&lt;br /&gt;
    SET total_amount = (&lt;br /&gt;
       SELECT COALESCE(SUM(quantity * price), 0.00)&lt;br /&gt;
       FROM order_items&lt;br /&gt;
       WHERE order_id = OLD.order_id&lt;br /&gt;
    )&lt;br /&gt;
    WHERE id = OLD.order_id;&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;COALESCE&amp;lt;/code&amp;gt; 関数は、最初のNULL以外の値を返す。&amp;lt;br&amp;gt;&lt;br /&gt;
全ての注文明細が削除された場合、SUM関数はNULLを返すため、COALESCEで0.00を返すようにしている。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーのデバッグ ==&lt;br /&gt;
トリガーのデバッグは、通常のストアドプロシージャと比べて難しい場合がある。&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーは自動的に実行されるため、エラーが発生した場合の原因特定が困難である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
デバッグ用のテーブルを作成して、トリガーの実行をログに記録する方法がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 CREATE TABLE trigger_debug_log (&lt;br /&gt;
    id INT AUTO_INCREMENT PRIMARY KEY,&lt;br /&gt;
    trigger_name VARCHAR(100),&lt;br /&gt;
    debug_info TEXT,&lt;br /&gt;
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP&lt;br /&gt;
 );&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガー内にデバッグ情報を記録する例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 CREATE TRIGGER users_before_insert_debug BEFORE INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- デバッグ情報を記録&lt;br /&gt;
    INSERT INTO trigger_debug_log (trigger_name, debug_info)&lt;br /&gt;
    VALUES (&amp;#039;users_before_insert&amp;#039;, CONCAT(&amp;#039;email=&amp;#039;, NEW.email, &amp;#039;,age=&amp;#039;, NEW.age));&lt;br /&gt;
 &lt;br /&gt;
    -- 通常の処理&lt;br /&gt;
    SET NEW.email = LOWER(TRIM(NEW.email));&lt;br /&gt;
    SET NEW.created_at = NOW();&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
開発環境では、&amp;lt;code&amp;gt;general_log&amp;lt;/code&amp;gt; を有効にしてクエリログを確認することもできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SET GLOBAL general_log = 1;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
general_logファイルの場所を確認する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 SHOW VARIABLES LIKE &amp;#039;general_log_file&amp;#039;;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;本番環境では、&amp;lt;code&amp;gt;general_log&amp;lt;/code&amp;gt; はパフォーマンスに影響を与えるため、通常は無効にしておく。&amp;lt;/u&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== トリガーの制限事項 ==&lt;br /&gt;
MySQLのトリガーには、いくつかの制限事項がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ トリガーの主な制限事項&lt;br /&gt;
! 制限事項 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| 同一テーブルへの変更不可 || トリガー内から、トリガーが設定されているテーブルへのINSERT / UPDATE / DELETEは実行できない。&amp;lt;br&amp;gt;これを行うと、再帰的なトリガー呼び出しが発生し、エラーになる。&lt;br /&gt;
|-&lt;br /&gt;
| COMMIT / ROLLBACK不可 || トリガー内で、COMMIT、ROLLBACK、START TRANSACTIONを実行できない。&amp;lt;br&amp;gt;トリガーは呼び出し元のトランザクション内で実行される。&lt;br /&gt;
|-&lt;br /&gt;
| RETURN文不可 || トリガー内でRETURN文を使用できない。&amp;lt;br&amp;gt;ストアドファンクションとは異なり、トリガーは値を返さない。&lt;br /&gt;
|-&lt;br /&gt;
| VIEWへのトリガー不可 || VIEWに対してトリガーを作成できない。&amp;lt;br&amp;gt;トリガーは、テーブルに対してのみ作成可能である。&lt;br /&gt;
|-&lt;br /&gt;
| LOCK TABLES不可 || トリガー内で &amp;lt;code&amp;gt;LOCK TABLES&amp;lt;/code&amp;gt; および &amp;lt;code&amp;gt;UNLOCK TABLES&amp;lt;/code&amp;gt; を使用できない。&lt;br /&gt;
|-&lt;br /&gt;
| ストアドプロシージャの制限 || トリガー内からCALLでストアドプロシージャを呼び出す場合、&amp;lt;br&amp;gt;そのプロシージャ内でもトリガーと同じ制限が適用される。&lt;br /&gt;
|-&lt;br /&gt;
| 直接再帰不可 || トリガーは直接再帰呼び出しできない。&amp;lt;br&amp;gt;ただし、カスケードによる間接的な呼び出しは可能である。&lt;br /&gt;
|-&lt;br /&gt;
| LOAD DATAでのパフォーマンス || &amp;lt;code&amp;gt;LOAD DATA&amp;lt;/code&amp;gt;文では、BEFOREトリガーが行ごとに実行されるため、&amp;lt;br&amp;gt;大量データのロード時にパフォーマンスに影響を与える。&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガー内から同一テーブルを変更しようとすると、エラーが発生する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 -- これはエラーになる&lt;br /&gt;
 CREATE TRIGGER invalid_trigger AFTER INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    -- 同一テーブルへのINSERTは不可&lt;br /&gt;
    INSERT INTO users (username) VALUES (&amp;#039;test&amp;#039;);  -- エラー&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
このような場合は、別のテーブルに書き込むか、BEFOREトリガーで値を変更する方法を検討する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガー内でトランザクション制御を行おうとすると、エラーが発生する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
 DELIMITER //&lt;br /&gt;
 &lt;br /&gt;
 -- これはエラーになる&lt;br /&gt;
 CREATE TRIGGER invalid_trigger AFTER INSERT ON users&lt;br /&gt;
 FOR EACH ROW&lt;br /&gt;
 BEGIN&lt;br /&gt;
    START TRANSACTION;  -- エラー&lt;br /&gt;
    INSERT INTO audit_log VALUES (...);&lt;br /&gt;
    COMMIT;  -- エラー&lt;br /&gt;
 END//&lt;br /&gt;
 &lt;br /&gt;
 DELIMITER ;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
トリガーは、呼び出し元のトランザクション内で実行されるため、トランザクション制御は呼び出し元で行う。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連ページ ==&lt;br /&gt;
* [[MySQL - ストアドプロシージャ]]&lt;br /&gt;
*: ストアドプロシージャの作成、実行、パラメータの使用方法&lt;br /&gt;
* [[MySQL - ストアドファンクション]]&lt;br /&gt;
*: ストアドファンクションの作成、戻り値の使用方法&lt;br /&gt;
* [[MySQL - イベントスケジューラ]]&lt;br /&gt;
*: 定期的なタスクの自動実行&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,MySQL,Trigger,トリガー,CREATE TRIGGER,DROP TRIGGER,BEFORE,AFTER,INSERT,UPDATE,DELETE,NEW,OLD,FOLLOWS,PRECEDES,Database,データベース,SQL,ストアドプロシージャ,監査ログ,データ検証,自動値設定,集計テーブル,SIGNAL,FOR EACH ROW,電気回路,電子回路,基板,プリント基板&lt;br /&gt;
|description={{PAGENAME}} - MySQLのトリガーの作成、変更、削除、BEFOREトリガー、AFTERトリガー、NEW / OLD疑似レコード、実用例、デバッグ方法に関する総合ガイド | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:MySQL]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>