1 # 触发器
2 # 一种MySQL数据库对象,它在表的某些事件发生时自动执行预定义的SQL语句
3 #触发器类型
4 # 行级触发器:在每一行受到影响时触发。
5 # 语句级触发器:在整个语句完成后触发(MySQL目前只支持行级触发器)。
6 # 触发器的事件
7 # BEFORE INSERT:在一条记录插入之前触发。
8 # AFTER INSERT:在一条记录插入之后触发。
9 # BEFORE UPDATE:在一条记录更新之前触发。
10 # AFTER UPDATE:在一条记录更新之后触发。
11 # BEFORE DELETE:在一条记录删除之前触发。
12 # AFTER DELETE:在一条记录删除之后触发。
13 # 触发器的作用
14 # 数据验证:在插入或更新数据时进行验证。
15 # 自动更新:在特定操作后自动更新某些字段。
16 # 日志记录:记录数据变化,进行审计。
17 # 复杂业务逻辑:实现一些复杂的业务逻辑。
18 # 语法格式
19 # CREATE TRIGGER trigger_name
20 # {BEFORE | AFTER} {INSERT | UPDATE | DELETE}
21 # ON table_name FOR EACH ROW
22 # BEGIN
23 # -- SQL语句
24 # END;
25 # 题目
26 # 1.创建一个触发器:在插入 orders 表的一行数据时,自动更新 products 表的库存数量
27 use test2;
28 CREATE TABLE products (
29 product_id INT PRIMARY KEY,
30 name VARCHAR(100),
31 stock_quantity INT
32 );
33
34 CREATE TABLE orders (
35 order_id INT PRIMARY KEY,
36 product_id INT,
37 quantity INT,
38 FOREIGN KEY (product_id) REFERENCES products(product_id)
39 );
40 create trigger after_insert_orders
41 after insert on orders for each row
42 begin
43 update products
44 set stock_quantity = stock_quantity - NEW.quantity
45 where product_id =NEW.product_id;
46 end;
47 # 2.创建一个触发器,在更新 products 表时,如果 stock_quantity 变为负数,则拒绝更新。
48 CREATE TABLE products (
49 product_id INT PRIMARY KEY,
50 product_name VARCHAR(100),
51 stock_quantity INT
52 );
53 create trigger before_update_products
54 before update on products
55 for each row
56 begin
57 if NEW.stock_quantity < 0 then
58 # 触发一个SQL错误。45000是通用错误代码,用于表示自定义的应用程序错误。
59 signal sqlstate '45000'
60 # 设置错误消息文本为“库存数量不能为负”。当错误触发时,数据库将返回这个消息。
61 set message_text ='库存数量不能为负';
62 end if;
63 end;
64 # 3.创建一个触发器,在删除 customers 表中的记录时,将删除的记录存入 deleted_customers 表中。
65 CREATE TABLE customers (
66 customer_id INT PRIMARY KEY,
67 customer_name VARCHAR(100)
68 );
69
70 CREATE TABLE deleted_customers (
71 customer_id INT,
72 customer_name VARCHAR(100),
73 deleted_at DATETIME
74 );
75 create trigger after_delete_customers
76 after delete on customers
77 for each row
78 begin
79 insert into deleted_customers(customer_id, customer_name, deleted_at)
80 value (OLD.customer_id,OLD.customer_name,now());
81 end;
82 #4.创建一个触发器,在插入 sales 表时,如果 quantity 小于等于 0,则拒绝插入。
83 CREATE TABLE sales (
84 sale_id INT PRIMARY KEY AUTO_INCREMENT,
85 product_id INT,
86 quantity INT,
87 sale_date DATETIME
88 );
89 create trigger before_insert_sales
90 before insert on sales
91 for each row
92 begin
93 if NEW.quantity <= 0 then
94 signal sqlstate '45000'
95 set message_text ='数量必须大于零';
96 end if;
97 end;
98 # 5.创建一个触发器,在更新 employees2 表时,自动更新 last_updated 字段为当前时间。
99 CREATE TABLE employees2 (
100 employee_id INT PRIMARY KEY AUTO_INCREMENT,
101 employee_name VARCHAR(100),
102 position VARCHAR(100),
103 last_updated DATETIME
104 );
105 create trigger before_update_employees
106 before update on employees2
107 for each row
108 begin
109 set new.last_updated = now();
110 end;