MySQLトリガーの使用と注意すべき点

MySQLトリガーの使用と注意すべき点

トリガーについて

実際の開発では、このような状況によく遭遇します。たとえば、情報の追加、削除、変更を行う際には、ログを記録する必要があります。通常のデータベースロジック操作を完了した後、ログテーブルに書き込む必要があるため、2段階の操作になり、より複雑になります。

たとえば、個人の情報を削除する場合、その人の買い物記録、配送先​​住所、お気に入りなどを削除する必要があります。この継続的な操作ではエラーが発生しやすく、一貫性と整合性が保証されません。このとき、トリガーを使用する必要があります。これにより、大量のビジネス ロジック コードを回避できるだけでなく、データの整合性もより確実に確保できます。

トリガーはテーブルに関連付けられたデータベース オブジェクトです。定義された条件が満たされたときにアクションをトリガーし、トリガーで定義された一連のステートメントを実行します。トリガーのこの機能は、アプリケーションがデータベース側でデータの整合性を確保するのに役立ちます。

これは、テーブル イベントに関連付けられた特別なストアド プロシージャであり、テーブルに対して操作 (挿入、削除、更新) が実行されたときにアクティブ化され、実行されます。

トリガーの使用

トリガーを作成する

トリガーを作成するための構文は次のとおりです。

CREATE TRIGGER トリガー名 トリガー時間 トリガーイベント ON t_name FOR EACH ROW トリガーステートメント

例:

trigger_name: トリガー名

tirgger_time: トリガー実行時点、データ操作前 (BEFORE) またはデータ操作後 (AFTER)

trigger_event: トリガー イベント、追加 (INSERT)、削除 (DELETE)、変更 (UPDATE)

t_name: t_nameテーブルにトリガーを作成することを意味します

trigger_stmt: トリガーの本体。SQL 文または BEGIN と END で囲まれた複数の文になります。

トリガーは永続テーブル (Permanent) にのみ作成でき、一時テーブル (Temporary) には作成できません。

FOR EACH ROW固定式。トリガーイベントを満たすレコードに対する操作はトリガーをトリガーすることを示します。

trigger_time には 2 種類、trigger_event には 3 種類あるため、組み合わせは全部で 6 つあります: BEFORE INSERT、BEFORE DELETE、BEFORE UPDATE、AFTER INSERT、AFTER DELETE、AFTER UPDATE

例 (最初に、トリガーがトリガーされたときに値を入力するログ テーブルを作成します):

/*まず、トリガーがトリガーされたときに値を入力するログ テーブルを作成します*/
mysql> `TriggerLog` が存在する場合はテーブルを削除します。
クエリは正常です。影響を受けた行は 0 行です

mysql> テーブル `TriggerLog` を作成します
(
  `id` INT auto_increment 主キー、
  `トリガー時間` VARCHAR(30)、
  `トリガーイベント` VARCHAR(30)、
  `メモ` VARCHAR(200)
);
クエリは正常です。影響を受けた行は 0 行です

挿入タイプトリガー:

マイSQL>
/*ここでSQLスクリプトは次のように終了すると宣言されています // */
区切り文字 //
存在する場合はトリガーを削除します。trig_after_insert;
各行の students に INSERT 後にトリガー trig_after_insert を作成します。
始める
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','insert',concat('新しい学生情報、ID:',cast(new.studentid as char))); を挿入します。
終わり //
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*SQL スクリプトの末尾を次のようにリセットします。*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*データを挿入*/
学生に(学生名、スコア、クラスID)値('トリガー1'、100、0)を挿入します。
クエリは正常、1 行が影響を受けました


マイSQL>
/*ログ テーブルをクエリして、トリガー書き込みがあるかどうかを確認します*/
`TriggerLog` から * を選択します。
+----+--------------+--------------+------------------------+
| id | トリガー時間 | トリガーイベント | メモ |
+----+--------------+--------------+------------------------+
| 1 | 後 | 挿入 | 新しい学生情報、ID:21 |
+----+--------------+--------------+------------------------+
セット内の1行

更新タイプトリガー:

マイSQL>
/*ここでSQLスクリプトは次のように終了すると宣言されています // */
区切り文字 //
存在する場合はトリガーを削除します trig_after_update;
各行の students の更新後にトリガー trig_after_update を作成します。
始める
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','update',concat('学生情報の更新、ID:',cast(new.studentid as char))); を挿入します。
終わり //
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*SQL スクリプトの末尾を次のようにリセットします。*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*データを更新する*/
学生を更新します。studentname='trigger1' のところ、score=99 を設定します。
クエリは正常、1 行が影響を受けました
一致した行: 1 変更された行: 1 警告: 0

マイSQL>
/* 更新時にトリガー書き込みがあるかどうかを確認するためにログ テーブルをクエリします */
`TriggerLog` から * を選択します。
+----+--------------+--------------+----------------------------+
| id | トリガー時間 | トリガーイベント | メモ |
+----+--------------+--------------+----------------------------+
| 1 | 後 | 挿入 | 新しい学生情報、ID:21 |
| 2 | 後 | 更新 | 学生情報を更新、ID:21 |
+----+--------------+---------------+----------------------------+
2行セット

削除タイプのトリガー:

マイSQL>
/*ここでSQLスクリプトは // で終わると宣言されています */
区切り文字 //
存在する場合はトリガーを削除します trig_after_delete;
各行の students に対して、DELETE 後にトリガー trig_after_delete を作成します。
始める
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','update',concat('delete student info,id:',cast(old.studentid as char))) を挿入します。
終わり //
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*SQL スクリプトの末尾を次のようにリセットします。*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/* データを削除 */
studentid=21 の students から削除します。
クエリは正常、1 行が影響を受けました

マイSQL>
/*ログを照会して、削除によって書き込みがトリガーされるかどうかを確認します*/
`TriggerLog` から * を選択します。
+----+--------------+---------------+----------------------------+
| id | トリガー時間 | トリガーイベント | メモ |
+----+--------------+--------------+----------------------------+
| 1 | 後 | 挿入 | 新しい学生情報、ID:21 |
| 2 | 後 | 更新 | 学生情報を更新、ID:21 |
| 3 | 後 | 更新 | 学生情報を削除、ID:21 |
+----+--------------+---------------+----------------------------+
3行セット

トリガーを表示

すべてのトリガーを表示

トリガーを表示; --構文
mysql> トリガーを表示します。
+-------------------+--------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+---------------------+--------------------+
| トリガー | イベント | テーブル | ステートメント | タイミング | 作成 | sql_mode | Definer | character_set_client | collat​​ion_connection | データベース照合 |
+-------------------+--------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+---------------------+--------------------+
| trig_after_insert | 挿入 | 学生 | 開始
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','insert',concat('新しい学生情報、ID:',cast(new.studentid as char))); を挿入します。
END | AFTER | NULL | STRICT_TRANS_TABLES、NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
| trig_after_update | 更新 | 学生 | 開始
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','update',concat('学生情報の更新、ID:',cast(new.studentid as char))); を挿入します。
END | AFTER | NULL | STRICT_TRANS_TABLES、NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
| trig_after_delete | 削除 | 学生 | 開始
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','update',concat('delete student info,id:',cast(old.studentid as char))) を挿入します。
END | AFTER | NULL | STRICT_TRANS_TABLES、NO_ENGINE_SUBSTITUTION | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
+-------------------+--------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+--------------------------------------------+----------------+---------------------+--------------------+
3行セット

トリガーの作成ステートメントを表示する

show create trigger trigger_name; --構文
mysql> トリガー trig_after_insert の作成を表示します。
+-------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| トリガー | sql_mode | SQL オリジナル ステートメント | character_set_client | collat​​ion_connection | データベース照合 |
+-------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| trig_after_insert | STRICT_TRANS_TABLES、NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` TRIGGER trig_after_insert AFTER INSERT ON students FOR EACH ROW
始める
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','insert',concat('新しい学生情報、ID:',cast(new.studentid as char))); を挿入します。
終了 | utf8 | utf8_general_ci | latin1_swedish_ci |
+-------------------+--------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
セット内の1行

トリガーの削除

トリガートリガ名を削除します。 --構文
mysql> トリガー trig_after_insert を削除します。
クエリは正常です。影響を受けた行は 0 行です
 
mysql> トリガー trig_after_insert の作成を表示します。
1360 - トリガーが存在しません

使用上の注意

新旧の違い

トリガーは、データベース内の各レコード行を対象とします。各データ行には、操作の前後に対応する状態があります。トリガーは、操作前の状態を古いキーワードに保存し、操作後の状態を新しいキーワードに保存します。

 new.cname -- 新しく追加された行 (または変更前の行) のデータの列 old.cname -- 削除された行 (または変更後の行) のデータの列

すべてのトリガーに古いものと新しいものがあるわけではないことに注意してください。

トリガータイプ新旧の活用
INSERTトリガー古いものはなく、新しいものだけがあります。新しいとは、追加されるデータ(挿入前)または追加されたデータ(挿入後)を意味します。
更新トリガー古いものと新しいものがあります。古いものは更新前のデータを表し、新しいものは更新後のデータを表します。
DELETEトリガー新しいものはなく、古いものだけです。古いものは、削除されようとしているデータ (削除前) または削除されたデータ (削除後) を示します。

実際、トリガーを作成してデータを取得するために、すでに new/old を使用しています。このテーブルに基づいて更新トリガー (trig_after_update) を変更し、変更前と変更後の出力を比較してみましょう。

マイSQL>
/*ここでSQLスクリプトは次のように終了すると宣言されています // */
区切り文字 //
存在する場合はトリガーを削除します trig_after_update;
各行の students の更新後にトリガー trig_after_update を作成します。
始める
 `TriggerLog`(`trigger_time`,`trigger_event`,`memo`) に値 ('after','update',concat('from:',old.studentname,',',old.score,' ','to:',new.studentname,',',new.score)) を挿入します。
終わり //
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*SQL スクリプトの末尾を次のようにリセットします。*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*成績と名前を更新*/
学生を更新する set score=106,studentname='trigger2' where studentid=17;
クエリは正常、1 行が影響を受けました
一致した行: 1 変更された行: 1 警告: 0

マイSQL>
/*更新前と更新後の値を古い値と新しい値に基づいて比較します*/
`TriggerLog` から * を選択します。
+----+--------------+--------------+--------------------------------------+
| id | トリガー時間 | トリガーイベント | メモ |
+----+--------------+--------------+--------------------------------------+
| 1 | 後 | 挿入 | 新しい学生情報、ID:21 |
| 2 | 後 | 更新 | 学生情報を更新、ID:21 |
| 3 | 後 | 更新 | 学生情報を削除、ID:21 |
| 4 | 更新後 | から:test2,101.00 へ:trigger2,106.00 |
+----+--------------+--------------+--------------------------------------+
4行セット

同じテーブルへの変更をトリガーできません

MySQL トリガーはこのテーブルに対して挿入、更新、または削除操作を実行できません。実行した場合はエラーが報告されます。

マイSQL>
/*ここでSQLスクリプトは次のように終了すると宣言されています // */
区切り文字 //
存在する場合はトリガーを削除します。trig_after_insert;
各行の students に INSERT 後にトリガー trig_after_insert を作成します。
始める
 生徒を更新します。score = score+1 を設定します。ただし、studentid は new.studentid です。
終わり //
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*SQL スクリプトの末尾を次のようにリセットします。*/
区切り文字 ;
クエリは正常です。影響を受けた行は 0 行です

マイSQL>
/*データを挿入した後、このテーブルの変更がトリガーされるため、エラーが報告されます*/
学生に(学生名、スコア、クラスID)値('trigger2'、101、0)を挿入します。
1442 - このストアド関数/トリガーを呼び出したステートメントによって既に使用されているため、ストアド関数/トリガー内のテーブル 'students' を更新できません。

まとめ

1. トリガーは、データベース内の関連テーブルを通じてカスケード変更を実装できます。つまり、データの変更、データ統計、データ複製など、1 つのテーブル内のデータの変更が他のテーブル内のデータに影響します。
2. データのセキュリティを確保し、セキュリティ チェックを実行し、データベースを操作するユーザーの権限を制限できます。
3. 複雑なロジックの実装に対して、データ整合性チェックと制約を実行できます。
4. トリガーは必要な場合にのみ使用してください。トリガーに頼りすぎると、データベースの構造に影響を及ぼし、データベースの実行および保守コストが増加します。
5. トリガーは BEFORE トリガーと AFTER トリガーに分かれており、その実行手順は、最初に BEFORE トリガーを実行し、次にビジネス スクリプトを実行し、最後に AFTER トリガーを実行するということになります。ステップが失敗すると、それ以上実行されなくなることに注意してください。トランザクション テーブルの場合はロールバックされます。非トランザクション テーブルの場合はロールバックできず、データの不整合が発生する可能性があります。

トリガーの2つの制限

1. トリガーは、クライアントにデータを返すストアド プロシージャを呼び出すことも、CALL ステートメントを使用する動的 SQL ステートメントを使用することもできません。ただし、ストアド プロシージャは、パラメーターを介してトリガーにデータを返すことができます。つまり、ストアド プロシージャまたは関数は、OUT または INOUT タイプのパラメーターを介してトリガーにデータを返すことができますが、データを直接返すプロシージャを呼び出すことはできません。
2. START TRANS-ACTION、COMMIT、ROLLBACK など、トランザクションを明示的または暗黙的に開始または終了するステートメントは、トリガーでは使用できません。

以上がMySQLトリガーの使い方と注意すべき点の詳しい内容です。MySQLトリガーの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください!

以下もご興味があるかもしれません:
  • MySQLトリガーの例の詳細な説明
  • MySQL でのトリガーとカーソルの紹介と使用
  • MySQLトリガーの使用と理解
  • MySQLでカーソルトリガーを使用する方法
  • MySQL トリガーの使用シナリオとメソッドの例
  • MySQLデータベーストリガーの詳細な説明
  • MySql ビュー、トリガー、ストアド プロシージャに関する簡単な説明
  • mysql トリガーの作成と使用例
  • MySQL トリガーの基本的な使い方(作成、表示、削除など)の詳細な説明
  • MySQLトリガーの使用

<<:  CSS を使用して半透明の背景と不透明なテキストを実現する例

>>:  Dockerコンテナの入退出方法の詳細な説明

推薦する

MySQL エラー: ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションの解決策を再起動してください

問題を見つける最近、以前のデータを入力していたときに、プログラムが突然次のエラーを報告しました。 [...

React 純粋関数コンポーネント setState がページ更新を更新しない問題の解決方法

目次問題の説明:原因分析:解決:補足: Reactでは、フックが使用されている場合、useState...

便利で使いやすいウェブアプリケーションを設計するための 10 のヒント

より使いやすい Web アプリケーションを設計するための 10 のヒントをご紹介します。ヒント1: ...

Dockerを使用してLaravel開発環境を構築するための完全な手順

序文この記事では、Docker を使用して、ローカル コンピューターにインストールされている開発スイ...

MySQL 文字列インデックスのより合理的な作成ルールに関する議論

序文MySQL インデックスの使用に関しては、これまでインデックスの最左接頭辞ルール、インデックス ...

Webpack ファイル パッケージ化エラー例外

webpack をパッケージ化する前に、次の作業が完了していることを確認する必要があります。 1) ...

html5 の新しいメソッドを使用して JavaScript で要素クラス名を操作する方法の詳細な説明

目次1. classList属性2. 実用化以前の JavaScript では、最初にクラス属性を取...

CSS3 の新しいレイアウト: flex の詳細な説明

Flexの基本概念フレックス レイアウト (フレックスはフレキシブル ボックスの略)、エラスティック...

mysql-joinsの具体的な使用方法

目次結合構文: 1. InnerJOIN: (内部結合) 2. LeftJOIN: (左結合) 3....

最も単純な ErrorBoundary コンポーネントをカプセル化して、React 例外を処理する

序文React 16から、子コンポーネントで発生したエラーを捕捉し、エラーログを記録し、ダウングレー...

Linux lessコマンド例の詳細な説明

ファイル名が少ないファイルを表示ファイル名を少なく | grep -n コンテンツを検索内容に応じて...

ubuntu16.04 で nginx を完全にアンインストールするための関連コマンド

nginx の概要nginx は、無料のオープンソースの高性能 HTTP サーバーおよびリバース プ...

Mysqlトランザクション操作の失敗を解決する方法

Mysqlトランザクション操作の失敗を解決する方法トランザクションの原子性: トランザクションは、デ...

React で遅延読み込みを使用して最初の画面の読み込み時間を短縮する方法

目次使用インストールルーティングでどのように使用しますか?読み込み速度の比較最近、中間およびバックエ...

Nginx+SpringBoot による負荷分散の実装例

負荷分散の概要Nginx の負荷分散実装を紹介する前に、負荷分散の分類について簡単に説明します。負荷...