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コンテナの入退出方法の詳細な説明

推薦する

document.getElementBy系メソッドがオブジェクトを取得できない問題を解決する

getElementByIdはオブジェクトを取得できませんブラウザがドキュメントを解析するときにはシ...

Alibaba Cloud ESC サーバー シングルノード MySQL の Docker デプロイメント

1. msyqlの高速バージョンをダウンロードする docker pull hub.c.163.co...

MYSQL での Truncate の使用法の詳細な説明

この記事のガイド: テーブル内のデータを削除するには、削除と切り捨ての 2 つの方法があります。TR...

Docker execは複数のコマンドを実行します

docker exec コマンドは、実行中のコンテナ内でコマンドを実行できます。 docker ex...

MySQL データベース分離レベルと MVCC の詳細な説明

目次1. 分離レベルコミットされていない読み取りREAD COMMITED (コミット読み取り/非反...

MySQL でグループ化した後、各グループの最大値を取得する詳細な例

MySQL でグループ化した後、各グループの最大値を取得する詳細な例1. テストデータベーステーブル...

HTMLページの読み込み速度を上げる方法

(1)HTTPリクエストを減らす。 (リソース ファイルをマージし、イメージ スプライトを使用します...

ドラッグフォトウォールを実現するネイティブJS

この記事では、ネイティブ JS で実装されたドラッグ可能な写真ウォールを紹介します。効果は次のとおり...

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

この記事では、CSS を使用して半透明の背景と不透明なテキストの効果を実現する方法の例を紹介します。...

rpm を使用して指定されたバージョンの docker (1.12.6) をインストールする詳細な手順

1. 理由システムが Centos7.3 の場合、yum install docker を使用して直...

Nginx http を https にアップグレードする手順を完了する

httpとhttpsの違いは一部のウェブサイトでは、http を開くと、安全ではないというメッセージ...

モバイルデバイス Web 開発における HTML ヘッドの書き方

コードをコピーコードは次のとおりです。 <ヘッド> <meta http-equi...

Linux の sudo 脆弱性により不正な特権アクセスが発生する可能性がある

Linux で新たに発見された sudo の脆弱性を悪用すると、特定のユーザーが root としてコ...

Kali Linux インストール VMware ツールのインストール プロセスと VM インストール vmtools ボタン グレー

Xiaobai は vmtools のインストールを記録します。 1. 意義と機能: VMWARE ...

CSS マルチレベルメニュー実装コード

これは、Web ページを Windows のスタート メニューなどのデスクトップ プログラムのように...