トリガーは特殊なタイプのストアド プロシージャであり、前に紹介したストアド プロシージャとは異なります。トリガーは主にイベントによってトリガーされ、自動的に呼び出されて実行されます。ストアド プロシージャは、ストアド プロシージャの名前で呼び出すことができます。
トリガーの主な機能は、参照整合性よりも複雑な 2 つ以上のテーブル間でデータの整合性と整合性を実現することです。これにより、テーブル内のデータの変更がデータベース設計者のルールによって決定されたビジネスに確実に準拠するようになります。
トリガーは、テーブルの挿入、更新、削除時に自動的に実行される特殊なストアド プロシージャです。トリガーは通常、より複雑なチェック制約を持つ制約で使用されます。
トリガーと通常のストアド プロシージャの違いは、トリガーが特定のテーブルに対して動作することです。更新、挿入、削除などの操作中に、システムはテーブル上の対応するトリガーを自動的に呼び出して実行します。
SQL Server 2005 のトリガーは、DML トリガーと DDL トリガーの 2 つのカテゴリに分類できます。DDL トリガーは、さまざまなデータ定義言語ステートメントに影響を与え、これらのステートメントには、create、alter、drop ステートメントがトリガーされます。
DML トリガーは次のように分類されます:
1. トリガー後 (後にトリガー)
a. トリガーの挿入
c. トリガーの代わりに (トリガー前に)
3 差分 f.トリガーは、特定の操作 (挿入、更新、削除) を実行した後にのみトリガーされる必要があり、テーブルでのみ定義できます。
定義された操作 (挿入、更新、削除) は実行されず、トリガー自体のみが実行されることを意味します。トリガーの代わりに、テーブルまたはビューにトリガーを定義できます。
挿入テーブルと削除テーブル
(1) 挿入されたテーブルは、INSERT または UPDATE ステートメントの影響を受ける行のコピーを保存するために使用されます。挿入または更新操作が実行されると、トリガーをアクティブ化する新しいデータ行がベース テーブルと挿入テーブルの両方に追加されます。
(2) 削除されたテーブルは、削除または更新ステートメントの影響を受ける行のコピーを保存するために使用されます。削除または更新操作が実行されると、指定された元のデータ行が実表から削除され、削除された表に転送されます。一般に、実表と削除された表には同じデータ行は存在しません。更新操作は 2 つのステップに分かれています。基本テーブルのデータ行を削除されたテーブルにコピーし、変更された新しいデータ行を挿入されたテーブルから基本テーブルにコピーします。つまり、更新操作の場合、削除されたテーブルには変更前の古い値が格納され、挿入されたテーブルには変更後の新しい値が格納されます。
トリガー作成構文の 4 つの要素:
1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/before) 4.触发事件(insert/update/delete)
delimiter &&create trigger trigger Nameafter/before insert/update/delete on 表名 for each row #这句话在mysql是固定的 beginsql语句; end&&
商品テーブル
mysql> create table g( -> id int auto_increment primary key, -> name varchar(10), -> num int -> );
注文テーブル
mysql> create table o( -> idd int auto_increment primary key, -> gid int, -> much int -> );
商品の挿入:
mysql> insert into g (name,num) value ('juzi',20);mysql> select * from g; +----+------+------+| id | name | num | +----+------+------+| 3 | juzi | 20 | +----+------+------+
トリガーを使用しなかった場合: 今、3 つの商品を販売したとします。 2 つのことを行う必要があります
1. 注文テーブルにレコードを挿入します
insert into o(gid,much) values(1,3);
2. 製品テーブルの品目 1 の残り数量を更新します
update g set num=num-3 where id=1;
delimiter & mysql> create trigger trg1 -> after insert on o -> for each row -> begin -> update g set num = num -3 where id = 1; -> end&
insert into o(gid,much) values(1,3)$
結果:
製品 1 の数量が 7 に変更されたことがわかります。これは、注文を挿入すると、トリガーが自動的に更新操作を実行することを意味します。
しかしここで問題が発生しました。トリガーの num と id がハードコーディングされているため、どの製品を購入しても、最終的には製品 1 の数量が更新されます。たとえば、別のレコードを注文テーブルに挿入します。 insert into o(gid,much) names(2,3) を実行すると、製品 1 の数量は 4 に変更されましたが、製品 2 の数量は変更されたことがわかります。これは明らかに私たちが望む結果ではありません。前に作成したトリガーを変更する必要があります。
create trigger tg2 after insert on o for each row begin update g set num=num-new.much where id=new.gid;(注意此处和第一个触发器的不同) end$
1.当用户撤销一个订单的时候,我们这边直接删除一个订单,我们是不是需要把对应的商品数量再加回去呢?
2.当用户修改一个订单的数量时,我们触发器修改怎么写?
我们先分析一下第一种情况:
监视地点:o表
监视事件:delete
触发时间:after
触发事件:update
对于delete而言:原本有一行,后来被删除,想引用被删除的这一行,用old来表示,old.列名可以引用被删除的行的值。
那我们的触发器就该这样写:
create trigger tg3 after delete on o for each row begin update g set num = num + old.much where id = old.gid;(注意这边的变化) end$
创建完毕。
再执行
delete from o where oid = 2$
会发现商品2的数量又变为10了。
第二种情况:
监视地点:o表
监视事件:update
触发时间:after
触发事件:update
对于update而言:被修改的行,修改前的数据,用old来表示,old.列名引用被修改之前行中的值;
修改的后的数据,用new来表示,new.列名引用被修改之后行中的值。
那我们的触发器就该这样写:
create trigger tg4 after update on o for each row begin update g set num = num+old.much-new.much where id = old/new.gid; end$
先把旧的数量恢复再减去新的数量就是修改后的数量了。
我们来测试下:先把商品表和订单表的数据都清掉,易于测试。
假设我们往商品表插入三个商品,数量都是10,
买3个商品1:
insert into o(gid,much) values(1,3)$
这时候商品1的数量变为7;
我们再修改插入的订单记录:
update o set much = 5 where oid = 1$
我们变为买5个商品1,这时候再查询商品表就会发现商品1的数量只剩5了,说明我们的触发器发挥作用了。
以上就是 【MySQL 12】触发器的内容,更多相关内容请关注PHP中文网(www.php.cn)!