Verified Commit a4aed8f1 authored by Kiryuu Sakuya's avatar Kiryuu Sakuya 🎵
Browse files

Update No.9

parent dad673d1
......@@ -2,14 +2,155 @@
## 名词解释
### 触发器
#### 特性
-`BEGIN ... END`
- 在增删改前或后触发
- 频率为针对每一行执行
- 定义在表上,附着在表上
- 极度消耗资源,能不用就不用
#### 如何写
```mysql
CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
```
## 预想的表结构
### 示例代码
#### 1. 设置一个触发器,该触发器仅允许 "misaka00251" 用户可以删除 employee 表内数据,否则出错
#### 1. 设置一个触发器,该触发器仅允许 "root" 用户可以删除 employee 表内数据,否则出错。
```mysql
SELECT USER();
DELIMITER //
CREATE TRIGGER user_limit BEFORE DELETE ON employee FOR EACH ROW
BEGIN
IF USER() != "root@%" THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Fuck you';
END IF;
END//
DELIMITER ;
CREATE USER 'example'@'localhost' IDENTIFIED BY 'example';
GRANT ALL PRIVILEGES ON studentdb.* TO example@localhost IDENTIFIED BY 'example';
```
然后换作 `example` 这个用户连接:
```mysql
USE employee;
DELETE FROM employee WHERE emp_no = 99999;
# 这个时候应该会说 `ERROR 1644 (45000): Fuck you` 了。
```
#### 2. 设置一个针对 employee 表的触发器,当有人操作 salary 列值时,触发器将自动将该操作者的名称和操作时间记录在一张表内,以便追踪。
```mysql
CREATE TABLE data_tracking (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
User varchar(50) NOT NULL,
Time DATETIME NOT NULL
);
DELIMITER //
CREATE TRIGGER track_modify_employee AFTER UPDATE ON employee FOR EACH ROW
BEGIN
IF (New.emp_no != Old.emp_no) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_name != Old.emp_name) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_sex != Old.emp_sex) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_dept != Old.emp_dept) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_title != Old.emp_title) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_date_hired != Old.emp_date_hired) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_birthday != Old.emp_birthday) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_salary != Old.emp_salary) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_addr != Old.emp_addr) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
IF (New.emp_mod_date != Old.emp_mod_date) THEN
INSERT INTO data_tracking (
ID, User, Time
) VALUES (
data_tracking.ID, USER(), NOW()
);
END IF;
END//
DELIMITER ;
# 来试试
UPDATE employee SET emp_no = "99998" WHERE emp_name = "龙玉涛";
SELECT * FROM data_tracking;
```
#### 3. 级联更新:当更新 employee 表中 emp_no 列的值时,同时更新 sales 表中的 sale_id 列的值,并且一次只能更新一行。
#### 4. 对 employee 表写一个 UPDATE 触发器。
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment