Auto commit

This commit is contained in:
smallkun 2025-03-18 18:23:20 +08:00
parent 4b5e81f1b3
commit f93fce1ea6
3 changed files with 578 additions and 0 deletions

View File

@ -0,0 +1,155 @@
### 语法结构
```sql
DELIMITER //
CREATE FUNCTION calculate_annual_salary (
monthly_salary DECIMAL(10, 2)
)
RETURNS DECIMAL(10, 2)
DETERMINISTIC | NOT DETERMINISTIC #结果确定/不确定
BEGIN
RETURN monthly_salary * 12;
END //
DELIMITER ;
```
### 表结构与数据
```sql
-- 创建数据库
CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用数据库
USE company;
-- 创建 department 表
CREATE TABLE department (
dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID主键',
dept_name VARCHAR(100) NOT NULL COMMENT '部门名称',
location VARCHAR(100) NOT NULL COMMENT '部门所在地'
);
-- 创建 job 表
CREATE TABLE job (
job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID主键',
job_title VARCHAR(100) NOT NULL COMMENT '职位名称',
min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资',
max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资'
);
-- 创建 employee 表
CREATE TABLE employee (
emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID主键',
emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名',
salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资',
hire_date DATE NOT NULL COMMENT '入职日期',
dept_id INT COMMENT '部门ID外键',
job_id INT COMMENT '职位ID外键',
FOREIGN KEY (dept_id) REFERENCES department(dept_id),
FOREIGN KEY (job_id) REFERENCES job(job_id)
);
INSERT INTO department (dept_name, location) VALUES
('HR', 'New York'),
('IT', 'San Francisco'),
('Finance', 'Chicago'),
('Marketing', 'Los Angeles'),
('Sales', 'Boston'),
('Operations', 'Houston'),
('Research', 'Seattle'),
('Customer Support', 'Austin');
INSERT INTO job (job_title, min_salary, max_salary) VALUES
('Manager', 60000.00, 100000.00),
('Developer', 50000.00, 80000.00),
('Analyst', 45000.00, 70000.00),
('Designer', 40000.00, 65000.00),
('Sales Executive', 35000.00, 60000.00),
('HR Specialist', 40000.00, 70000.00),
('Finance Analyst', 50000.00, 75000.00),
('Marketing Coordinator', 45000.00, 70000.00),
('Operations Manager', 55000.00, 90000.00),
('Research Scientist', 60000.00, 95000.00),
('Customer Support Representative', 35000.00, 55000.00);
INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES
('Alice', 70000.00, '2020-01-15', 1, 1),
('Bob', 65000.00, '2019-03-22', 2, 2),
('Charlie', 55000.00, '2018-07-30', 2, 3),
('David', 60000.00, '2021-05-10', 3, 4),
('Eva', 50000.00, '2017-11-05', 4, 5),
('Frank', 75000.00, '2016-09-12', 5, 1),
('Grace', 48000.00, '2022-02-20', 1, 2),
('Henry', 52000.00, '2021-08-15', 2, 3),
('Ivy', 58000.00, '2020-04-10', 3, 4),
('Jack', 62000.00, '2019-12-01', 4, 5),
('Katie', 53000.00, '2021-07-25', 5, 6),
('Leo', 67000.00, '2018-05-18', 6, 7),
('Mona', 49000.00, '2020-11-30', 7, 8),
('Nina', 71000.00, '2019-02-14', 8, 9),
('Oscar', 56000.00, '2022-03-05', 1, 10),
('Paul', 63000.00, '2021-09-12', 2, 11),
('Quincy', 54000.00, '2020-06-20', 3, 1),
('Rachel', 59000.00, '2019-08-15', 4, 2),
('Steve', 68000.00, '2018-12-10', 5, 3),
('Tina', 51000.00, '2022-01-22', 6, 4),
('Uma', 72000.00, '2021-04-18', 7, 5),
('Victor', 57000.00, '2020-07-30', 8, 6),
('Wendy', 64000.00, '2019-10-05', 1, 7),
('Xander', 50000.00, '2022-05-12', 2, 8),
('Yara', 69000.00, '2021-03-25', 3, 9),
('Zack', 55000.00, '2020-09-15', 4, 10),
('Amy', 61000.00, '2019-06-20', 5, 11),
('Brian', 74000.00, '2018-04-10', 6, 1),
('Cathy', 52000.00, '2022-07-18', 7, 2),
('Derek', 67000.00, '2021-12-01', 8, 3);
```
### 练习题
#### 练习题 1: 计算员工年薪
创建一个存储函数 `calculate_annual_salary`,接受员工的月薪作为参数,返回其年薪(假设年薪为月薪的 12 倍)。
#### 练习题 2: 计算员工工龄
创建一个存储函数 `calculate_years_of_service`,接受员工的入职日期作为参数,返回该员工的工龄(以年为单位)。
#### 练习题 3: 根据部门计算平均工资
创建一个存储函数 `calculate_avg_salary_by_dept`,接受部门 ID 作为参数,返回该部门的平均工资。
#### 练习题 4: 根据职位计算平均工资
创建一个存储函数 `calculate_avg_salary_by_job`,接受职位 ID 作为参数,返回该职位的平均工资。
#### 练习题 5: 计算员工税后工资
创建一个存储函数 `calculate_net_salary`,接受员工的工资作为参数,返回其税后工资(假设税率为 15%)。
#### 练习题 6: 判断员工是否满足加薪条件
创建一个存储函数 `is_eligible_for_raise`接受员工的工资和工龄作为参数返回一个布尔值1 或 0。加薪条件如下
- 如果工资低于 60000 且工龄大于等于 3 年,返回 1满足条件
- 否则返回 0不满足条件
#### 练习题 7: 计算部门总工资
创建一个存储函数 `calculate_total_salary_by_dept`,接受部门 ID 作为参数,返回该部门所有员工的总工资。
#### 练习题 8: 计算职位总工资
创建一个存储函数 `calculate_total_salary_by_job`,接受职位 ID 作为参数,返回该职位所有员工的总工资。
#### 练习题 9: 判断员工是否属于高薪部门
创建一个存储函数 `is_high_salary_department`,接受部门 ID 作为参数返回一个布尔值1 或 0。如果该部门的平均工资大于等于 70000返回 1高薪部门否则返回 0非高薪部门
#### 练习题 10: 计算员工的总收入
创建一个存储函数 `calculate_total_income`,接受员工的工资和奖金(假设奖金为工资的 10%)作为参数,返回其总收入(工资 + 奖金)。

View File

@ -0,0 +1,226 @@
### 语法结构
```sql
DELIMITER //
CREATE PROCEDURE GetEmployeeCountByDept (
IN dept_id INT,
OUT employee_count INT
)
BEGIN
SELECT COUNT(*) INTO employee_count
FROM employee
WHERE dept_id = dept_id;
END //
DELIMITER ;
IF condition THEN
-- 条件为真时执行的代码
ELSEIF another_condition THEN
-- 另一个条件为真时执行的代码
ELSE
-- 所有条件都不满足时执行的代码
END IF;
CASE expression
WHEN value1 THEN
-- 当 expression = value1 时执行的代码
WHEN value2 THEN
-- 当 expression = value2 时执行的代码
ELSE
-- 当 expression 不匹配任何值时执行的代码
END CASE;
CASE
WHEN condition1 THEN
-- 当 condition1 为真时执行的代码
WHEN condition2 THEN
-- 当 condition2 为真时执行的代码
ELSE
-- 当所有条件都不满足时执行的代码
END CASE;
```
---
### 表结构与数据
```sql
-- 创建数据库
CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用数据库
USE company;
-- 创建 department 表
CREATE TABLE department (
dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID主键',
dept_name VARCHAR(100) NOT NULL COMMENT '部门名称',
location VARCHAR(100) NOT NULL COMMENT '部门所在地'
);
-- 创建 job 表
CREATE TABLE job (
job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID主键',
job_title VARCHAR(100) NOT NULL COMMENT '职位名称',
min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资',
max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资'
);
-- 创建 employee 表
CREATE TABLE employee (
emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID主键',
emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名',
salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资',
hire_date DATE NOT NULL COMMENT '入职日期',
dept_id INT COMMENT '部门ID外键',
job_id INT COMMENT '职位ID外键',
FOREIGN KEY (dept_id) REFERENCES department(dept_id),
FOREIGN KEY (job_id) REFERENCES job(job_id)
);
INSERT INTO department (dept_name, location) VALUES
('HR', 'New York'),
('IT', 'San Francisco'),
('Finance', 'Chicago'),
('Marketing', 'Los Angeles'),
('Sales', 'Boston'),
('Operations', 'Houston'),
('Research', 'Seattle'),
('Customer Support', 'Austin');
INSERT INTO job (job_title, min_salary, max_salary) VALUES
('Manager', 60000.00, 100000.00),
('Developer', 50000.00, 80000.00),
('Analyst', 45000.00, 70000.00),
('Designer', 40000.00, 65000.00),
('Sales Executive', 35000.00, 60000.00),
('HR Specialist', 40000.00, 70000.00),
('Finance Analyst', 50000.00, 75000.00),
('Marketing Coordinator', 45000.00, 70000.00),
('Operations Manager', 55000.00, 90000.00),
('Research Scientist', 60000.00, 95000.00),
('Customer Support Representative', 35000.00, 55000.00);
INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES
('Alice', 70000.00, '2020-01-15', 1, 1),
('Bob', 65000.00, '2019-03-22', 2, 2),
('Charlie', 55000.00, '2018-07-30', 2, 3),
('David', 60000.00, '2021-05-10', 3, 4),
('Eva', 50000.00, '2017-11-05', 4, 5),
('Frank', 75000.00, '2016-09-12', 5, 1),
('Grace', 48000.00, '2022-02-20', 1, 2),
('Henry', 52000.00, '2021-08-15', 2, 3),
('Ivy', 58000.00, '2020-04-10', 3, 4),
('Jack', 62000.00, '2019-12-01', 4, 5),
('Katie', 53000.00, '2021-07-25', 5, 6),
('Leo', 67000.00, '2018-05-18', 6, 7),
('Mona', 49000.00, '2020-11-30', 7, 8),
('Nina', 71000.00, '2019-02-14', 8, 9),
('Oscar', 56000.00, '2022-03-05', 1, 10),
('Paul', 63000.00, '2021-09-12', 2, 11),
('Quincy', 54000.00, '2020-06-20', 3, 1),
('Rachel', 59000.00, '2019-08-15', 4, 2),
('Steve', 68000.00, '2018-12-10', 5, 3),
('Tina', 51000.00, '2022-01-22', 6, 4),
('Uma', 72000.00, '2021-04-18', 7, 5),
('Victor', 57000.00, '2020-07-30', 8, 6),
('Wendy', 64000.00, '2019-10-05', 1, 7),
('Xander', 50000.00, '2022-05-12', 2, 8),
('Yara', 69000.00, '2021-03-25', 3, 9),
('Zack', 55000.00, '2020-09-15', 4, 10),
('Amy', 61000.00, '2019-06-20', 5, 11),
('Brian', 74000.00, '2018-04-10', 6, 1),
('Cathy', 52000.00, '2022-07-18', 7, 2),
('Derek', 67000.00, '2021-12-01', 8, 3);
```
---
### 练习题
#### 练习题 1: 插入新员工
创建一个存储过程 `add_employee`接受员工姓名、工资、入职日期、部门ID和职位ID作为参数并将其插入到 `employee` 表中。
#### 练习题 2: 更新员工工资
创建一个存储过程 `update_employee_salary`接受员工ID和新的工资作为参数更新该员工的工资。
#### 练习题 3: 删除员工
创建一个存储过程 `delete_employee`接受员工ID作为参数删除该员工的记录。
#### 练习题 4: 查询部门员工
创建一个存储过程 `get_department_employees`接受部门ID作为参数返回该部门所有员工的详细信息。
#### 练习题 5: 查询职位员工
创建一个存储过程 `get_job_employees`接受职位ID作为参数返回该职位所有员工的详细信息。
#### 练习题 6: 计算部门平均工资
创建一个存储过程 `calculate_avg_salary_by_dept`接受部门ID作为参数返回该部门的平均工资。
#### 练习题 7: 计算职位平均工资
创建一个存储过程 `calculate_avg_salary_by_job`接受职位ID作为参数返回该职位的平均工资。
#### 练习题 8: 查询高薪员工
创建一个存储过程 `get_high_salary_employees`,接受一个工资阈值作为参数,返回所有工资高于该阈值的员工。
#### 练习题 9: 查询员工工龄
创建一个存储过程 `get_employee_years_of_service`接受员工ID作为参数返回该员工的工龄以年为单位
#### 练习题 10: 查询部门员工总数
创建一个存储过程 `get_department_employee_count`接受部门ID作为参数返回该部门的员工总数。
#### 练习题 11: 查询职位员工总数
创建一个存储过程 `get_job_employee_count`接受职位ID作为参数返回该职位的员工总数。
#### 练习题 12: 查询员工详细信息
创建一个存储过程 `get_employee_details`接受员工ID作为参数返回该员工的姓名、工资、部门名称和职位名称。
#### 练习题 13: 查询部门最高工资
创建一个存储过程 `get_department_max_salary`接受部门ID作为参数返回该部门的最高工资。
#### 练习题 14: 查询职位最低工资
创建一个存储过程 `get_job_min_salary`接受职位ID作为参数返回该职位的最低工资。
#### 练习题 15: 查询员工工资排名
创建一个存储过程 `get_employee_salary_rank`接受员工ID作为参数返回该员工在公司中的工资排名。
#### 练习题 16: 查询部门工资总和
创建一个存储过程 `get_department_total_salary`接受部门ID作为参数返回该部门所有员工的工资总和。
#### 练习题 17: 查询职位工资总和
创建一个存储过程 `get_job_total_salary`接受职位ID作为参数返回该职位所有员工的工资总和。
#### 练习题 18: 查询员工入职年份分布
创建一个存储过程 `get_employees_by_hire_year`,接受年份作为参数,返回该年份入职的所有员工。
#### 练习题 19: 查询部门工资分布
创建一个存储过程 `get_department_salary_distribution`接受部门ID作为参数返回该部门工资的分布情况如最高、最低、平均工资
#### 练习题 20: 查询职位工资分布
创建一个存储过程 `get_job_salary_distribution`接受职位ID作为参数返回该职位工资的分布情况如最高、最低、平均工资

197
2207/触发器练习题.md Normal file
View File

@ -0,0 +1,197 @@
### 语法结构
```sql
DELIMITER //
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
FOR EACH ROW
BEGIN
-- 触发器的逻辑代码
-- 可以包含 SQL 语句、流程控制语句(如 IF、CASE 等)、变量声明等
END//
DELIMITER ;
```
### 表结构和数据
```sql
-- 创建数据库
CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用数据库
USE company;
-- 创建 department 表
CREATE TABLE department (
dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID主键',
dept_name VARCHAR(100) NOT NULL COMMENT '部门名称',
location VARCHAR(100) NOT NULL COMMENT '部门所在地'
);
-- 创建 job 表
CREATE TABLE job (
job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID主键',
job_title VARCHAR(100) NOT NULL COMMENT '职位名称',
min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资',
max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资'
);
-- 创建 employee 表
CREATE TABLE employee (
emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID主键',
emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名',
salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资',
hire_date DATE NOT NULL COMMENT '入职日期',
dept_id INT COMMENT '部门ID外键',
job_id INT COMMENT '职位ID外键',
FOREIGN KEY (dept_id) REFERENCES department(dept_id),
FOREIGN KEY (job_id) REFERENCES job(job_id)
);
INSERT INTO department (dept_name, location) VALUES
('HR', 'New York'),
('IT', 'San Francisco'),
('Finance', 'Chicago'),
('Marketing', 'Los Angeles'),
('Sales', 'Boston'),
('Operations', 'Houston'),
('Research', 'Seattle'),
('Customer Support', 'Austin');
INSERT INTO job (job_title, min_salary, max_salary) VALUES
('Manager', 60000.00, 100000.00),
('Developer', 50000.00, 80000.00),
('Analyst', 45000.00, 70000.00),
('Designer', 40000.00, 65000.00),
('Sales Executive', 35000.00, 60000.00),
('HR Specialist', 40000.00, 70000.00),
('Finance Analyst', 50000.00, 75000.00),
('Marketing Coordinator', 45000.00, 70000.00),
('Operations Manager', 55000.00, 90000.00),
('Research Scientist', 60000.00, 95000.00),
('Customer Support Representative', 35000.00, 55000.00);
INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES
('Alice', 70000.00, '2020-01-15', 1, 1),
('Bob', 65000.00, '2019-03-22', 2, 2),
('Charlie', 55000.00, '2018-07-30', 2, 3),
('David', 60000.00, '2021-05-10', 3, 4),
('Eva', 50000.00, '2017-11-05', 4, 5),
('Frank', 75000.00, '2016-09-12', 5, 1),
('Grace', 48000.00, '2022-02-20', 1, 2),
('Henry', 52000.00, '2021-08-15', 2, 3),
('Ivy', 58000.00, '2020-04-10', 3, 4),
('Jack', 62000.00, '2019-12-01', 4, 5),
('Katie', 53000.00, '2021-07-25', 5, 6),
('Leo', 67000.00, '2018-05-18', 6, 7),
('Mona', 49000.00, '2020-11-30', 7, 8),
('Nina', 71000.00, '2019-02-14', 8, 9),
('Oscar', 56000.00, '2022-03-05', 1, 10),
('Paul', 63000.00, '2021-09-12', 2, 11),
('Quincy', 54000.00, '2020-06-20', 3, 1),
('Rachel', 59000.00, '2019-08-15', 4, 2),
('Steve', 68000.00, '2018-12-10', 5, 3),
('Tina', 51000.00, '2022-01-22', 6, 4),
('Uma', 72000.00, '2021-04-18', 7, 5),
('Victor', 57000.00, '2020-07-30', 8, 6),
('Wendy', 64000.00, '2019-10-05', 1, 7),
('Xander', 50000.00, '2022-05-12', 2, 8),
('Yara', 69000.00, '2021-03-25', 3, 9),
('Zack', 55000.00, '2020-09-15', 4, 10),
('Amy', 61000.00, '2019-06-20', 5, 11),
('Brian', 74000.00, '2018-04-10', 6, 1),
('Cathy', 52000.00, '2022-07-18', 7, 2),
('Derek', 67000.00, '2021-12-01', 8, 3);
```
### `SIGNAL` 语句的基本语法
```sql
SIGNAL SQLSTATE '状态码'
SET MESSAGE_TEXT = '错误消息';
```
- **SQLSTATE**:一个 5 字符的字符串表示错误的状态码。MySQL 使用 `'45000'` 表示用户定义的错误。
- **MESSAGE_TEXT**:自定义的错误消息,用于描述错误的原因。
### 练习题
#### 练习题 1: 工资范围验证
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据之前,检查员工的工资是否在其对应职位的 `min_salary``max_salary` 范围内。如果超出范围,阻止插入并抛出错误。
#### 练习题 2: 自动更新部门人数
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门人数(假设 `department` 表新增一个字段 `employee_count`)。
#### 练习题 3: 工资变更日志
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `salary` 字段后,将变更记录插入到一个新的日志表 `salary_log` 中,记录员工 ID、旧工资、新工资和变更时间。
#### 练习题 4: 删除员工时备份数据
创建一个触发器 `before_employee_delete`,在删除 `employee` 表数据之前,将被删除的员工数据插入到一个备份表 `employee_backup` 中。
#### 练习题 5: 自动设置默认职位
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果未指定 `job_id`,则自动将其设置为 `job` 表中的默认职位(假设默认职位的 `job_id` 为 1
#### 练习题 6: 防止修改入职日期
创建一个触发器 `before_employee_update`,在更新 `employee` 表数据时,防止修改 `hire_date` 字段。如果尝试修改,抛出错误。
#### 练习题 7: 自动计算工龄
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动计算员工的工龄(以年为单位),并将其存储到一个新字段 `years_of_service` 中。
#### 练习题 8: 防止删除部门
创建一个触发器 `before_department_delete`,在删除 `department` 表数据之前,检查该部门是否还有员工。如果有员工,阻止删除并抛出错误。
#### 练习题 9: 自动更新职位工资范围
创建一个触发器 `after_job_update`,在更新 `job` 表的 `min_salary``max_salary` 字段后,自动调整 `employee` 表中相关员工的工资,使其符合新的工资范围。
#### 练习题 10: 记录部门变更
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `dept_id` 字段后,将变更记录插入到一个新的日志表 `department_change_log` 中,记录员工 ID、旧部门 ID、新部门 ID 和变更时间。
#### 练习题 11: 防止插入重复职位
创建一个触发器 `before_job_insert`,在插入 `job` 表数据之前,检查职位名称是否已存在。如果存在,阻止插入并抛出错误。
#### 练习题 12: 自动更新员工总数
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新一个统计表 `employee_statistics` 中的员工总数。
#### 练习题 13: 防止修改部门所在地
创建一个触发器 `before_department_update`,在更新 `department` 表数据时,防止修改 `location` 字段。如果尝试修改,抛出错误。
#### 练习题 14: 自动调整工资
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果工资低于职位的最低工资,则自动将其调整为最低工资。
#### 练习题 15: 记录职位变更
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `job_id` 字段后,将变更记录插入到一个新的日志表 `job_change_log` 中,记录员工 ID、旧职位 ID、新职位 ID 和变更时间。
#### 练习题 16: 防止删除职位
创建一个触发器 `before_job_delete`,在删除 `job` 表数据之前,检查该职位是否还有员工。如果有员工,阻止删除并抛出错误。
#### 练习题 17: 自动更新部门平均工资
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门平均工资(假设 `department` 表新增一个字段 `avg_salary`)。
#### 练习题 18: 防止插入未来入职日期
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,检查 `hire_date` 是否晚于当前日期。如果是,阻止插入并抛出错误。
#### 练习题 19: 自动生成员工编号
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动生成一个唯一的员工编号(格式为 `EMP-年份-序号`,例如 `EMP-2023-001`),并将其存储到一个新字段 `emp_code` 中。
#### 练习题 20: 记录员工离职
创建一个触发器 `after_employee_delete`,在删除 `employee` 表数据之后,将被删除的员工信息插入到一个离职记录表 `employee_exit_log` 中,记录员工 ID、姓名、离职时间和原因假设原因由用户输入