Auto commit
This commit is contained in:
parent
92bbbfb089
commit
f6f91c0fd4
1051
最后两周/C语言同步练习答案.md
Normal file
1051
最后两周/C语言同步练习答案.md
Normal file
File diff suppressed because it is too large
Load Diff
0
最后两周/C语言基础进阶合集版编程题.md
Normal file
0
最后两周/C语言基础进阶合集版编程题.md
Normal file
BIN
最后两周/C语言基础进阶合集版编程题.pdf
Normal file
BIN
最后两周/C语言基础进阶合集版编程题.pdf
Normal file
Binary file not shown.
651
最后两周/MySQL数据库操作综合练习题答案.md
Normal file
651
最后两周/MySQL数据库操作综合练习题答案.md
Normal file
@ -0,0 +1,651 @@
|
|||||||
|
### 练习一
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#(1)创建数据库
|
||||||
|
CREATE DATABASE test04_Market DEFAULT CHARACTER SET utf8;
|
||||||
|
USE test04_Market;
|
||||||
|
#(2)创建数据表
|
||||||
|
CREATE TABLE customers(
|
||||||
|
c_num INT(11) PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
c_name VARCHAR(50),
|
||||||
|
c_contact VARCHAR(50),
|
||||||
|
c_city VARCHAR(50),
|
||||||
|
c_birth DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
#(3)更改字段的位置
|
||||||
|
#AFTER/BEFORE 字段名 设置位置在指定字段前/后
|
||||||
|
ALTER TABLE 表名 MODIFY 字段名 数据类型 AFTER/BEFORE 字段名;
|
||||||
|
ALTER TABLE customers MODIFY c_contact VARCHAR(50) AFTER c_birth;
|
||||||
|
#(4)更改字段的数据类型
|
||||||
|
ALTER TABLE customers MODIFY c_name VARCHAR(70);
|
||||||
|
#(5)更改字段名
|
||||||
|
ALTER TABLE customers CHANGE c_contact c_phone VARCHAR(50);
|
||||||
|
#(6)添加字段
|
||||||
|
ALTER TABLE customers ADD c_gender CHAR(1);
|
||||||
|
#(7)更改表名
|
||||||
|
ALTER TABLE customers RENAME TO customers_info;
|
||||||
|
#(8)删除字段
|
||||||
|
ALTER TABLE customers_info DROP c_city;
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#(1)创建表时 添加外键约束并指定外键约束名称
|
||||||
|
CREATE TABLE orders(
|
||||||
|
o_num INT(11) PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
o_date DATE,
|
||||||
|
c_id INT(11),
|
||||||
|
CONSTRAINT fk_cid FOREIGN KEY(c_id) REFERENCES customers_info(c_num)
|
||||||
|
);
|
||||||
|
#(2)
|
||||||
|
#删除指定外键
|
||||||
|
ALTER TABLE orders DROP FOREIGN KEY orders_ibfk_1;
|
||||||
|
#删除指定表
|
||||||
|
DROP TABLE orders;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习二
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#(1)创建表、插入记录
|
||||||
|
CREATE TABLE pet(
|
||||||
|
`name` VARCHAR(20) NOT NULL COMMENT '宠物名称',
|
||||||
|
`owner` VARCHAR(20) COMMENT '宠物主人',
|
||||||
|
species VARCHAR(20) NOT NULL COMMENT '种类',
|
||||||
|
sex CHAR(1) NOT NULL COMMENT '性别',
|
||||||
|
birth YEAR NOT NULL COMMENT '出生日期',
|
||||||
|
death YEAR COMMENT '死亡日期'
|
||||||
|
);
|
||||||
|
INSERT INTO pet()
|
||||||
|
VALUES
|
||||||
|
('Fluffy', 'Harold', 'cat', 'f', 2003, 2010),
|
||||||
|
('Claws', 'Gwen', 'cat', 'm', 2004,NULL ),
|
||||||
|
('Buffy', NULL, 'dog', 'f', 2009, NULL),
|
||||||
|
('Fang', 'Benny', 'dog', 'm', 2000, NULL),
|
||||||
|
('Bowser', 'Diane', 'dog', 'm', 2003, 2009),
|
||||||
|
('Chirpy', NULL, 'bird', 'f', 2008, NULL);
|
||||||
|
#(2)更新记录
|
||||||
|
UPDATE pet
|
||||||
|
SET `owner` = 'Kevin'
|
||||||
|
WHERE `name` = 'Fang';
|
||||||
|
#(3)
|
||||||
|
UPDATE pet
|
||||||
|
SET `owner` = 'Kevin'
|
||||||
|
WHERE `owner` IS NULL;
|
||||||
|
#(4)
|
||||||
|
DELETE FROM pet
|
||||||
|
WHERE death IS NOT NULL;
|
||||||
|
#(5)
|
||||||
|
TRUNCATE pet;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习三
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#1.创建数据库
|
||||||
|
CREATE DATABASE test_compay DEFAULT CHARACTER SET utf8;
|
||||||
|
|
||||||
|
#2.创建表
|
||||||
|
CREATE TABLE department(
|
||||||
|
depid INT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
depname VARCHAR(20) NOT NULL,
|
||||||
|
deinfo VARCHAR(50)
|
||||||
|
);
|
||||||
|
CREATE TABLE employee(
|
||||||
|
empid INT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(20) NOT NULL,
|
||||||
|
sex CHAR(1) NOT NULL DEFAULT '男',
|
||||||
|
title VARCHAR(20) NOT NULL,
|
||||||
|
birthday DATE NOT NULL,
|
||||||
|
depid INT,
|
||||||
|
CONSTRAINT fk_eid_did FOREIGN KEY(depid) REFERENCES department(depid)
|
||||||
|
);
|
||||||
|
CREATE TABLE salary(
|
||||||
|
empid INT,
|
||||||
|
basesalary DECIMAL(10, 2),
|
||||||
|
titleSalary DECIMAL(10, 2),
|
||||||
|
decuction DECIMAL(10, 2)
|
||||||
|
);
|
||||||
|
#3添加外键并设置级联更新、级联删除
|
||||||
|
ALTER TABLE salary ADD CONSTRAINT fk_sal_eid FOREIGN KEY(empid)
|
||||||
|
REFERENCES employee(empid) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||||
|
#4插入记录
|
||||||
|
INSERT INTO department (depid, depname, deinfo)
|
||||||
|
VALUES
|
||||||
|
(111, '生产部', NULL),
|
||||||
|
(222, '销售部', NULL),
|
||||||
|
(333, '人事部', NULL),
|
||||||
|
(444, '财务部', '负责公司财务管理'),
|
||||||
|
(555, '技术部', '负责技术研发与支持'),
|
||||||
|
(666, '市场部', '负责市场推广与品牌建设'),
|
||||||
|
(777, '客服部', '负责客户服务与支持'),
|
||||||
|
(888, '采购部', '负责公司物资采购'),
|
||||||
|
(999, '法务部', '负责公司法律事务'),
|
||||||
|
(1010, '行政部', '负责公司日常行政管理'),
|
||||||
|
(1011, '研发部', '负责新产品研发'),
|
||||||
|
(1012, '培训部', '负责员工培训与发展');
|
||||||
|
|
||||||
|
INSERT INTO employee (empid, name, sex, title, birthday, depid)
|
||||||
|
VALUES
|
||||||
|
(1001, '张三', '男', '高级工程师', '1975-1-1', 111),
|
||||||
|
(1002, '李四', '女', '助工', '1985-1-1', 111),
|
||||||
|
(1003, '王五', '男', '工程师', '1978-11-11', 222),
|
||||||
|
(1004, '赵六', '男', '工程师', '1999-1-1', 222),
|
||||||
|
(1005, '陈七', '女', '会计师', '1980-5-15', 444),
|
||||||
|
(1006, '刘八', '男', '软件工程师', '1990-8-20', 555),
|
||||||
|
(1007, '孙九', '女', '市场经理', '1985-12-25', 666),
|
||||||
|
(1008, '周十', '男', '客服专员', '1992-3-10', 777),
|
||||||
|
(1009, '吴十一', '女', '采购经理', '1988-7-22', 888),
|
||||||
|
(1010, '郑十二', '男', '法务顾问', '1983-9-30', 999),
|
||||||
|
(1011, '王十三', '女', '行政助理', '1995-4-18', 1010),
|
||||||
|
(1012, '李十四', '男', '研发工程师', '1991-11-5', 1011),
|
||||||
|
(1013, '赵十五', '女', '培训讲师', '1987-6-12', 1012),
|
||||||
|
(1014, '孙十六', '男', '技术支持', '1993-2-14', 555),
|
||||||
|
(1015, '杨十七', '女', '销售代表', '1994-8-8', 222);
|
||||||
|
|
||||||
|
INSERT INTO salary (empid, basesalary, titleSalary, decuction)
|
||||||
|
VALUES
|
||||||
|
(1001, 2200, 1100, 200),
|
||||||
|
(1002, 1200, 200, NULL),
|
||||||
|
(1003, 2900, 700, 200),
|
||||||
|
(1004, 1950, 700, 150),
|
||||||
|
(1005, 2500, 800, 100),
|
||||||
|
(1006, 3000, 1200, 250),
|
||||||
|
(1007, 2800, 1000, 200),
|
||||||
|
(1008, 1800, 300, 50),
|
||||||
|
(1009, 3200, 900, 300),
|
||||||
|
(1010, 3500, 1000, 400),
|
||||||
|
(1011, 2000, 400, 100),
|
||||||
|
(1012, 3100, 1100, 200),
|
||||||
|
(1013, 2700, 800, 150),
|
||||||
|
(1014, 2300, 700, 100),
|
||||||
|
(1015, 2600, 600, 200);
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#5
|
||||||
|
SELECT e.empid, e.`name`, e.title, d.depname, s.basesalary + s.titleSalary, s.basesalary + s.titleSalary-IFNULL(s.decuction, 0)
|
||||||
|
FROM employee e, department d, salary s
|
||||||
|
WHERE e.depid = d.depid AND e.empid = s.empid;
|
||||||
|
#6
|
||||||
|
SELECT e.`name`, s.basesalary
|
||||||
|
FROM employee e, department d, salary s
|
||||||
|
WHERE e.depid = d.depid AND e.empid = s.empid AND d.depname = '销售部';
|
||||||
|
#7
|
||||||
|
SELECT *
|
||||||
|
FROM employee e
|
||||||
|
WHERe e.`name` LIKE '张%' AND TIMESTAMPDIFF(YEAR,e.birthday, NOW()) < 40;
|
||||||
|
#8
|
||||||
|
SELECT e.`name`, s.basesalary, s.titleSalary
|
||||||
|
FROM employee e, salary s
|
||||||
|
WHERE e.sex = '男' AND e.empid AND s.empid;
|
||||||
|
#9
|
||||||
|
SELECT e.`name`, e.title, d.depname
|
||||||
|
FROM employee e, department d, salary s
|
||||||
|
WHERE e.depid = d.depid AND e.empid = s.empid AND s.basesalary < 2000;
|
||||||
|
#10
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM employee;
|
||||||
|
#11
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM department d;
|
||||||
|
#12
|
||||||
|
SELECT AVG(s.basesalary + s.titleSalary), MAX(s.basesalary + s.titleSalary), MIN(s.basesalary + s.titleSalary)
|
||||||
|
FROM employee e, salary s
|
||||||
|
WHERE e.empid = s.empid;
|
||||||
|
#13
|
||||||
|
SELECT d.depname, AVG(s.basesalary + s.titleSalary)
|
||||||
|
FROM employee e, salary s, department d
|
||||||
|
WHERE e.empid = s.empid AND e.depid = d.depid
|
||||||
|
GROUP BY d.depid;
|
||||||
|
#14
|
||||||
|
SELECT d.depname, AVG(s.basesalary + s.titleSalary) avg
|
||||||
|
FROM employee e, salary s, department d
|
||||||
|
WHERE e.empid = s.empid AND e.depid = d.depid
|
||||||
|
GROUP BY d.depid
|
||||||
|
HAVING avg<2000;
|
||||||
|
#15
|
||||||
|
SELECT e.empid, e.`name`, s.basesalary, s.titleSalary, s.decuction
|
||||||
|
FROM employee e, salary s, department d
|
||||||
|
WHERE e.empid = s.empid AND e.depid = d.depid
|
||||||
|
ORDER BY s.titleSalary, s.basesalary;
|
||||||
|
#16
|
||||||
|
SELECT e.empid, e.`name`, e.birthday,
|
||||||
|
IF(YEAR(e.birthday) < 1980, '老年',
|
||||||
|
IF(YEAR(e.birthday)< 1990, '中年', '青壮年'))
|
||||||
|
FROM employee e;
|
||||||
|
#17
|
||||||
|
SELECT e.*, depname
|
||||||
|
FROM employee e, department d
|
||||||
|
WHERE e.depid = d.depid;
|
||||||
|
#18
|
||||||
|
SELECT d.*, e.*
|
||||||
|
FROM employee e, department d
|
||||||
|
WHERE e.depid = d.depid;
|
||||||
|
#19
|
||||||
|
SELECT *
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.title LIKE '%工程师%' AND e.sex = '男';
|
||||||
|
#20
|
||||||
|
SELECT d.depname, e.sex, COUNT(*), AVG(s.basesalary)
|
||||||
|
FROM employee e, department d, salary s
|
||||||
|
WHERE e.depid = d.depid AND e.empid = s.empid
|
||||||
|
GROUP BY d.depid, e.sex;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习四
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#1
|
||||||
|
CREATE DATABASE test_school DEFAULT CHARACTER SET 'UTF8';
|
||||||
|
#2
|
||||||
|
DROP TABLE department;
|
||||||
|
CREATE TABLE department(
|
||||||
|
depNo INT(10) PRIMARY KEY COMMENT '部门号',
|
||||||
|
depName VARCHAR(50) NOT NULL COMMENT '部门名称',
|
||||||
|
depNote VARCHAR(20) COMMENT '部门备注'
|
||||||
|
);
|
||||||
|
CREATE TABLE teacher(
|
||||||
|
number INT PRIMARY KEY COMMENT '教工号',
|
||||||
|
`name` VARCHAR(30) NOT NULL COMMENT '姓名',
|
||||||
|
sex VARCHAR(4) COMMENT '性别',
|
||||||
|
birth DATE COMMENT '出生日期',
|
||||||
|
depNo INT COMMENT '部门号',
|
||||||
|
salary FLOAT COMMENT '工资',
|
||||||
|
address VARCHAR(100) COMMENT '家庭住址'
|
||||||
|
);
|
||||||
|
INSERT INTO department()
|
||||||
|
VALUES
|
||||||
|
(601, '软件技术系', '软件技术等专业'),
|
||||||
|
(602, '网络技术系', '多媒体技术等专业'),
|
||||||
|
(603, '艺术设计系', '广告艺术设计等专业'),
|
||||||
|
(604, '管理工程系', '连锁经营管理等专业');
|
||||||
|
|
||||||
|
INSERT INTO teacher()
|
||||||
|
VALUES
|
||||||
|
(2001, 'Tom', '女', '1970-01-10', 602, 4500, '四川省绵阳市'),
|
||||||
|
(2002, 'Lucy', '男', '1983-12-18', 601, 2500, '北京市昌平区'),
|
||||||
|
(2003, 'Mike', '男', '1990-06-01', 604, 1500, '重庆市渝中区'),
|
||||||
|
(2004, 'James', '女', '1980-10-20', 602, 3500, '四川省成都市'),
|
||||||
|
(2005, 'Jack', '男', '1975-05-30', 603, 1200, '重庆市南岸区');
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#4
|
||||||
|
SELECT *
|
||||||
|
FROM teacher;
|
||||||
|
#5
|
||||||
|
SELECT t.number '教工号', d.depName '部门名称'
|
||||||
|
FROM teacher t, department d
|
||||||
|
WHERE t.depNo = d.depNo AND t.address LIKE '%北京%';
|
||||||
|
#6
|
||||||
|
SELECT t.number, t.`name`
|
||||||
|
FROM teacher t
|
||||||
|
ORDER BY t.salary DESC
|
||||||
|
LIMIT 1;
|
||||||
|
#7
|
||||||
|
SELECT t.number, t.`name`
|
||||||
|
FROM teacher t
|
||||||
|
WHERE t.salary BETWEEN 2500 AND 4000;
|
||||||
|
#8
|
||||||
|
SELECT t.`name`, t.sex, t.salary
|
||||||
|
FROM teacher t, department d
|
||||||
|
WHERE t.depNo = d.depNo AND d.depName = '网络技术系';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习五
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 创建数据库并设置字符集为 utf8mb4
|
||||||
|
CREATE DATABASE test_student CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
USE test_student;
|
||||||
|
|
||||||
|
-- 创建表 Classes
|
||||||
|
CREATE TABLE Classes (
|
||||||
|
专业 VARCHAR(50),
|
||||||
|
班级 VARCHAR(50),
|
||||||
|
姓名 VARCHAR(50),
|
||||||
|
性别 VARCHAR(10),
|
||||||
|
座位 INT
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 向表 Classes 插入数据
|
||||||
|
INSERT INTO Classes (专业, 班级, 姓名, 性别, 座位) VALUES
|
||||||
|
('计算机网络', '1班', '张三', '男', 8),
|
||||||
|
('软件工程', '2班', '李四', '男', 12),
|
||||||
|
('计算机维护', '1班', '王五', '男', 9),
|
||||||
|
('计算机网络', '2班', 'LILY', '女', 15),
|
||||||
|
('软件工程', '1班', '小强', '男', 20),
|
||||||
|
('计算机维护', '1班', 'CoCo', '女', 18);
|
||||||
|
|
||||||
|
-- 创建表 Score
|
||||||
|
CREATE TABLE Score (
|
||||||
|
姓名 VARCHAR(50),
|
||||||
|
英语 INT,
|
||||||
|
数学 INT,
|
||||||
|
语文 INT
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 向表 Score 插入数据
|
||||||
|
INSERT INTO Score (姓名, 英语, 数学, 语文) VALUES
|
||||||
|
('张三', 65, 75, 98),
|
||||||
|
('李四', 87, 45, 86),
|
||||||
|
('王五', 98, 85, 65),
|
||||||
|
('LILY', 75, 86, 87),
|
||||||
|
('小强', 85, 60, 58),
|
||||||
|
('CoCo', 96, 87, 70);
|
||||||
|
|
||||||
|
-- 创建表 Records
|
||||||
|
CREATE TABLE Records (
|
||||||
|
姓名 VARCHAR(50),
|
||||||
|
记录 VARCHAR(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 向表 Records 插入数据
|
||||||
|
INSERT INTO Records (姓名, 记录) VALUES
|
||||||
|
('小强', '迟到'),
|
||||||
|
('小强', '事假'),
|
||||||
|
('李四', '旷课'),
|
||||||
|
('李四', '旷课'),
|
||||||
|
('李四', '迟到'),
|
||||||
|
('CoCo', '病假'),
|
||||||
|
('LILY', '事假');
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
#3
|
||||||
|
UPDATE score s
|
||||||
|
SET s.`语文` = 88
|
||||||
|
WHERE s.`姓名` = '张三';
|
||||||
|
|
||||||
|
#4
|
||||||
|
SELECT AVG(s.`英语`), AVG(s.`数学`), AVG(s.`语文`)
|
||||||
|
FROM classes c, score s
|
||||||
|
WHERE c.`姓名` = s.`姓名` AND c.`班级` = 1 AND c.`专业` = '计算机维护';
|
||||||
|
|
||||||
|
#5
|
||||||
|
SELECT *
|
||||||
|
FROM score s
|
||||||
|
WHERE s.`数学` < 60 OR s.`英语` < 60 OR s.`语文` < 60;
|
||||||
|
|
||||||
|
#6
|
||||||
|
SELECT *
|
||||||
|
FROM score s
|
||||||
|
WHERE s.`姓名` IN (
|
||||||
|
SELECT r.`姓名`
|
||||||
|
FROM records r
|
||||||
|
GROUP BY r.`姓名`
|
||||||
|
HAVING COUNT(*) > 2
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习六
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 创建数据库 test_xuankedb 并设置字符集为 utf8mb4
|
||||||
|
CREATE DATABASE test_xuankedb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
USE test_xuankedb;
|
||||||
|
|
||||||
|
-- 创建学生表 Student
|
||||||
|
CREATE TABLE Student (
|
||||||
|
Sn0 VARCHAR(20) PRIMARY KEY, -- 学号,主键
|
||||||
|
Sname VARCHAR(50), -- 姓名
|
||||||
|
Ssex VARCHAR(10), -- 性别
|
||||||
|
Sage INT, -- 年龄
|
||||||
|
Sdept VARCHAR(50) -- 所在系
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建课程表 Course
|
||||||
|
CREATE TABLE Course (
|
||||||
|
Cn0 VARCHAR(20) PRIMARY KEY, -- 课程号,主键
|
||||||
|
Cname VARCHAR(100), -- 课程名
|
||||||
|
Cpn0 VARCHAR(20), -- 选修课号
|
||||||
|
Ccredit INT -- 学分
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建成绩表 SG
|
||||||
|
CREATE TABLE SG (
|
||||||
|
Sn0 VARCHAR(20), -- 学号
|
||||||
|
Cn0 VARCHAR(20), -- 课程号
|
||||||
|
Grade INT, -- 成绩
|
||||||
|
PRIMARY KEY (Sn0, Cn0), -- 复合主键 (学号, 课程号)
|
||||||
|
FOREIGN KEY (Sn0) REFERENCES Student(Sn0), -- 外键,引用 Student 表
|
||||||
|
FOREIGN KEY (Cn0) REFERENCES Course(Cn0) -- 外键,引用 Course 表
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO Student (Sno, Sname, Ssex, Sage, Sdept, Scome) VALUES
|
||||||
|
('05001', '张三', '男', 20, '计算机系', '2021-09-01'),
|
||||||
|
('05002', '李四', '女', 21, '数学系', '2021-09-01'),
|
||||||
|
('05003', '王五', '男', 22, '计算机系', '2021-09-01'),
|
||||||
|
('05004', '李洋', '男', 19, '物理系', '2021-09-01'),
|
||||||
|
('05019', '赵六', '女', 20, '计算机系', '2021-09-01');
|
||||||
|
|
||||||
|
INSERT INTO Course (Cno, Cname, Cpno, Ccredit) VALUES
|
||||||
|
('1', '数据库', NULL, 4),
|
||||||
|
('2', '数学', NULL, 3),
|
||||||
|
('3', '物理', NULL, 3),
|
||||||
|
('4', '操作系统', '1', 4);
|
||||||
|
|
||||||
|
INSERT INTO SG (Sno, Cno, Grade) VALUES
|
||||||
|
('05001', '1', 85),
|
||||||
|
('05001', '2', 90),
|
||||||
|
('05002', '1', 78),
|
||||||
|
('05002', '3', 88),
|
||||||
|
('05003', '1', 92),
|
||||||
|
('05003', '4', 76),
|
||||||
|
('05004', '3', 95),
|
||||||
|
('05019', '1', 80),
|
||||||
|
('05019', '4', 85);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习七
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 创建数据库 test_library 并设置字符集为 utf8mb4
|
||||||
|
CREATE DATABASE test_library CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
USE test_library;
|
||||||
|
|
||||||
|
-- 创建表 press(出版社)
|
||||||
|
CREATE TABLE press (
|
||||||
|
pressid INT PRIMARY KEY, -- 出版社编号,主键
|
||||||
|
pressname VARCHAR(100), -- 出版社名称
|
||||||
|
address VARCHAR(100) -- 出版社地址
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建表 sort(种类)
|
||||||
|
CREATE TABLE sort (
|
||||||
|
sortno INT PRIMARY KEY, -- 种类编号,主键
|
||||||
|
scount INT, -- 数量
|
||||||
|
describes VARCHAR(100) -- 描述
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建表 book(图书)
|
||||||
|
CREATE TABLE book (
|
||||||
|
bid INT PRIMARY KEY, -- 图书编号,主键
|
||||||
|
bname VARCHAR(100), -- 图书名称
|
||||||
|
bsortno INT, -- 种类编号
|
||||||
|
pressid INT, -- 出版社编号
|
||||||
|
FOREIGN KEY (bsortno) REFERENCES sort(sortno), -- 外键,引用 sort 表
|
||||||
|
FOREIGN KEY (pressid) REFERENCES press(pressid) -- 外键,引用 press 表
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 向 press 表插入数据
|
||||||
|
INSERT INTO press (pressid, pressname, address) VALUES
|
||||||
|
(100, '外研社', '上海'),
|
||||||
|
(101, '北大出版社', '北京'),
|
||||||
|
(102, '教育出版社', '北京');
|
||||||
|
|
||||||
|
-- 向 sort 表插入数据
|
||||||
|
INSERT INTO sort (sortno, scount, describes) VALUES
|
||||||
|
(11, 50, '小说'),
|
||||||
|
(12, 100, '科幻'),
|
||||||
|
(13, 100, '神话');
|
||||||
|
|
||||||
|
-- 向 book 表插入数据
|
||||||
|
INSERT INTO book (bid, bname, bsortno, pressid) VALUES
|
||||||
|
(1, '红与黑', 11, 100),
|
||||||
|
(2, '幻城', 12, 102),
|
||||||
|
(3, '希腊神话', 13, 102);
|
||||||
|
|
||||||
|
#5
|
||||||
|
SELECT b.*
|
||||||
|
FROM book b, press p
|
||||||
|
WHERE p.pressid = b.pressid AND p.pressid = 100;
|
||||||
|
|
||||||
|
#6
|
||||||
|
SELECT b.*
|
||||||
|
FROM book b, press p
|
||||||
|
WHERE p.pressid = b.pressid AND p.pressname = '外研社';
|
||||||
|
|
||||||
|
#7
|
||||||
|
SELECT *
|
||||||
|
FROM sort s
|
||||||
|
WHERE s.scount > 100;
|
||||||
|
|
||||||
|
#8
|
||||||
|
SELECT p.*
|
||||||
|
FROM book b, press p
|
||||||
|
WHERE p.pressid = b.pressid
|
||||||
|
GROUP BY b.pressid
|
||||||
|
HAVING COUNT(*) = (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM book b, press p
|
||||||
|
WHERE p.pressid = b.pressid
|
||||||
|
GROUP BY b.pressid
|
||||||
|
ORDER BY COUNT(*) DESC
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 练习八
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 创建数据库 test_tour 并设置字符集为 utf8mb4
|
||||||
|
CREATE DATABASE test_tour CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
USE test_tour;
|
||||||
|
|
||||||
|
-- 创建表 agency(旅行社表)
|
||||||
|
CREATE TABLE agency (
|
||||||
|
id INT PRIMARY KEY, -- 旅行社编号,主键
|
||||||
|
name VARCHAR(100) NOT NULL, -- 旅行社名
|
||||||
|
address VARCHAR(100) NOT NULL, -- 旅行社地址
|
||||||
|
areaid INT -- 所属区域编号
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 创建表 travel(旅行线路表)
|
||||||
|
CREATE TABLE travel (
|
||||||
|
tid INT PRIMARY KEY, -- 旅行线路编号,主键
|
||||||
|
time VARCHAR(50) NOT NULL, -- 所需时间
|
||||||
|
position VARCHAR(100) NOT NULL, -- 目的地
|
||||||
|
money FLOAT, -- 花费
|
||||||
|
aid INT NOT NULL, -- 所属旅行社编号
|
||||||
|
count INT, -- 报名人数
|
||||||
|
FOREIGN KEY (aid) REFERENCES agency(id) -- 外键,引用 agency 表
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 向 agency 表插入数据
|
||||||
|
INSERT INTO agency (id, name, address) VALUES
|
||||||
|
(101, '青年旅行社', '北京海淀'),
|
||||||
|
(102, '天天旅行社', '天津海院');
|
||||||
|
|
||||||
|
-- 向 travel 表插入数据
|
||||||
|
INSERT INTO travel (tid, time, position, money, aid, count) VALUES
|
||||||
|
(1, '5天', '八达岭', 3000, 101, 10),
|
||||||
|
(2, '7天', '水长城', 5000, 101, 14),
|
||||||
|
(3, '8天', '水长城', 6000, 102, 11);
|
||||||
|
|
||||||
|
#4
|
||||||
|
SELECT a.*
|
||||||
|
FROM travel t, agency a
|
||||||
|
WHERE t.aid =a.id
|
||||||
|
GROUP BY a.id
|
||||||
|
HAVING COUNT(*) = (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM travel t, agency a
|
||||||
|
WHERE t.aid =a.id
|
||||||
|
GROUP BY a.id
|
||||||
|
ORDER BY COUNT(*) DESC
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
#5
|
||||||
|
SELECT t.*
|
||||||
|
FROM travel t
|
||||||
|
WHERE t.count = (
|
||||||
|
SELECT t.count
|
||||||
|
FROM travel t
|
||||||
|
ORDER BY t.count DESC
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
#6
|
||||||
|
SELECT *
|
||||||
|
FROM travel t
|
||||||
|
WHERE t.money < 5000;
|
||||||
|
|
||||||
|
#7
|
||||||
|
SELECT a.`name`
|
||||||
|
FROM travel t, agency a
|
||||||
|
WHERE t.aid =a.id AND t.money = (
|
||||||
|
SELECT t.money
|
||||||
|
FROM travel t, agency a
|
||||||
|
WHERE t.aid =a.id
|
||||||
|
ORDER BY t.money DESC
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
#8
|
||||||
|
SELECT SUM(t.time)
|
||||||
|
FROM travel t, agency a
|
||||||
|
WHERE t.aid =a.id AND a.`name` = '青年旅行社';
|
||||||
|
```
|
||||||
|
|
155
最后两周/存储函数练习题.md
Normal file
155
最后两周/存储函数练习题.md
Normal 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%)作为参数,返回其总收入(工资 + 奖金)。
|
529
最后两周/存储过程练习题.md
Normal file
529
最后两周/存储过程练习题.md
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
### 语法结构
|
||||||
|
|
||||||
|
```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` 表中。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS add_employee;
|
||||||
|
CREATE PROCEDURE add_employee(IN emp_name VARCHAR(100), IN salary DECIMAL(10,2), IN hire_date DATE, IN dept_id INT, IN job_id INT)
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO employee()
|
||||||
|
VALUES(DEFAULT, emp_name, salary, hire_date, dept_id, job_id);
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL add_employee('李泽龙', 6666, '2025-3-20', 1, 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 2: 更新员工工资
|
||||||
|
|
||||||
|
创建一个存储过程 `update_employee_salary`,接受员工ID和新的工资作为参数,更新该员工的工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS update_employee_salary;
|
||||||
|
CREATE PROCEDURE update_employee_salary(IN emp_id INT, IN salary DECIMAL(10, 2))
|
||||||
|
BEGIN
|
||||||
|
UPDATE employee e
|
||||||
|
SET e.salary = salary
|
||||||
|
WHERE e.emp_id = emp_id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL update_employee_salary(1, 60000);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 3: 删除员工
|
||||||
|
|
||||||
|
创建一个存储过程 `delete_employee`,接受员工ID作为参数,删除该员工的记录。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS delete_employee;
|
||||||
|
CREATE PROCEDURE delete_employee(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM employee
|
||||||
|
WHERE emp_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL delete_employee(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 4: 查询部门员工
|
||||||
|
|
||||||
|
创建一个存储过程 `get_department_employees`,接受部门ID作为参数,返回该部门所有员工的详细信息。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_department_employees;
|
||||||
|
CREATE PROCEDURE get_department_employees(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT e.*
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_department_employees(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 5: 查询职位员工
|
||||||
|
|
||||||
|
创建一个存储过程 `get_job_employees`,接受职位ID作为参数,返回该职位所有员工的详细信息。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_job_employees;
|
||||||
|
CREATE PROCEDURE get_job_employees(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT e.*
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.job_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_job_employees(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 6: 计算部门平均工资
|
||||||
|
|
||||||
|
创建一个存储过程 `calculate_avg_salary_by_dept`,接受部门ID作为参数,返回该部门的平均工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS calculate_avg_salary_by_dept;
|
||||||
|
CREATE PROCEDURE calculate_avg_salary_by_dept(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT AVG(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL calculate_avg_salary_by_dept(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 7: 计算职位平均工资
|
||||||
|
|
||||||
|
创建一个存储过程 `calculate_avg_salary_by_job`,接受职位ID作为参数,返回该职位的平均工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS calculate_avg_salary_by_job;
|
||||||
|
CREATE PROCEDURE calculate_avg_salary_by_job(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT AVG(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.job_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL calculate_avg_salary_by_job(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 8: 查询高薪员工
|
||||||
|
|
||||||
|
创建一个存储过程 `get_high_salary_employees`,接受一个工资阈值作为参数,返回所有工资高于该阈值的员工。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_high_salary_employees;
|
||||||
|
CREATE PROCEDURE get_high_salary_employees(IN sal DECIMAL(10, 2))
|
||||||
|
BEGIN
|
||||||
|
SELECT e.*
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.salary > sal;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_high_salary_employees(50000);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 9: 查询员工工龄
|
||||||
|
|
||||||
|
创建一个存储过程 `get_employee_years_of_service`,接受员工ID作为参数,返回该员工的工龄(以年为单位)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_employee_years_of_service;
|
||||||
|
CREATE PROCEDURE get_employee_years_of_service(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT -TIMESTAMPDIFF(YEAR,NOW(),e.hire_date)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.emp_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_employee_years_of_service(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 10: 查询部门员工总数
|
||||||
|
|
||||||
|
创建一个存储过程 `get_department_employee_count`,接受部门ID作为参数,返回该部门的员工总数。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_department_employee_count;
|
||||||
|
CREATE PROCEDURE get_department_employee_count(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_department_employee_count(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 11: 查询职位员工总数
|
||||||
|
|
||||||
|
创建一个存储过程 `get_job_employee_count`,接受职位ID作为参数,返回该职位的员工总数。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_job_employee_count;
|
||||||
|
CREATE PROCEDURE get_job_employee_count(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.job_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_job_employee_count(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 12: 查询员工详细信息
|
||||||
|
|
||||||
|
创建一个存储过程 `get_employee_details`,接受员工ID作为参数,返回该员工的姓名、工资、部门名称和职位名称。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_employee_details;
|
||||||
|
CREATE PROCEDURE get_employee_details(IN emp_id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT e.emp_name, e.salary, d.dept_name, j.job_title
|
||||||
|
FROM employee e, department d, job j
|
||||||
|
WHERE e.emp_id = emp_id AND e.dept_id = d.dept_id AND e.job_id = j.job_id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_employee_details(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 13: 查询部门最高工资
|
||||||
|
|
||||||
|
创建一个存储过程 `get_department_max_salary`,接受部门ID作为参数,返回该部门的最高工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_department_max_salary;
|
||||||
|
CREATE PROCEDURE get_department_max_salary(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT MAX(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_department_max_salary(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 14: 查询职位最低工资
|
||||||
|
|
||||||
|
创建一个存储过程 `get_job_min_salary`,接受职位ID作为参数,返回该职位的最低工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_job_min_salary;
|
||||||
|
CREATE PROCEDURE get_job_min_salary(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT MIN(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_job_min_salary(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 15: 查询员工工资排名
|
||||||
|
|
||||||
|
创建一个存储过程 `get_employee_salary_rank`,接受员工ID作为参数,返回该员工在公司中的工资排名。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_employee_salary_rank;
|
||||||
|
CREATE PROCEDURE get_employee_salary_rank(IN emp_id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT COUNT(*) + 1
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.salary > (
|
||||||
|
SELECT e.salary
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.emp_id = emp_id
|
||||||
|
);
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL get_employee_salary_rank(2);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 16: 查询部门工资总和
|
||||||
|
|
||||||
|
创建一个存储过程 `get_department_total_salary`,接受部门ID作为参数,返回该部门所有员工的工资总和。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_department_total_salary;
|
||||||
|
CREATE PROCEDURE get_department_total_salary(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT SUM(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_department_total_salary(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 17: 查询职位工资总和
|
||||||
|
|
||||||
|
创建一个存储过程 `get_job_total_salary`,接受职位ID作为参数,返回该职位所有员工的工资总和。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_job_total_salary;
|
||||||
|
CREATE PROCEDURE get_job_total_salary(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT SUM(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.job_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_job_total_salary(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 18: 查询员工入职年份分布
|
||||||
|
|
||||||
|
创建一个存储过程 `get_employees_by_hire_year`,接受年份作为参数,返回该年份入职的所有员工。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_employees_by_hire_year;
|
||||||
|
CREATE PROCEDURE get_employees_by_hire_year(IN y INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT *
|
||||||
|
FROM employee e
|
||||||
|
WHERE YEAR(e.hire_date) = y;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_employees_by_hire_year(2020);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 19: 查询部门工资分布
|
||||||
|
|
||||||
|
创建一个存储过程 `get_department_salary_distribution`,接受部门ID作为参数,返回该部门工资的分布情况(如最高、最低、平均工资)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_department_salary_distribution;
|
||||||
|
CREATE PROCEDURE get_department_salary_distribution(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT MAX(e.salary), MIN(e.salary), AVG(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_department_salary_distribution(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 20: 查询职位工资分布
|
||||||
|
|
||||||
|
创建一个存储过程 `get_job_salary_distribution`,接受职位ID作为参数,返回该职位工资的分布情况(如最高、最低、平均工资)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP PROCEDURE IF EXISTS get_job_salary_distribution;
|
||||||
|
CREATE PROCEDURE get_job_salary_distribution(IN id INT)
|
||||||
|
BEGIN
|
||||||
|
SELECT MAX(e.salary), MIN(e.salary), AVG(e.salary)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.job_id = id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL get_job_salary_distribution(1);
|
||||||
|
```
|
||||||
|
|
610
最后两周/触发器练习题.md
Normal file
610
最后两周/触发器练习题.md
Normal file
@ -0,0 +1,610 @@
|
|||||||
|
### 语法结构
|
||||||
|
|
||||||
|
```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` 范围内。如果超出范围,阻止插入并抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
IF NEW.salary > (
|
||||||
|
SELECT j.max_salary
|
||||||
|
FROM job j
|
||||||
|
WHERE j.job_id = NEW.job_id
|
||||||
|
) OR NEW.salary < (
|
||||||
|
SELECT j.min_salary
|
||||||
|
FROM job j
|
||||||
|
WHERE j.job_id = NEW.job_id
|
||||||
|
) THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '工资值错误,不在职务工资范围内';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
INSERT INTO employee
|
||||||
|
VALUES(DEFAULT, '雷昊', 0, NOW(), 1, 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 2: 自动更新部门人数
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门人数(假设 `department` 表新增一个字段 `employee_count`)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER TABLE department ADD employee_count INT UNSIGNED;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_insert;
|
||||||
|
CREATE TRIGGER after_employee_insert
|
||||||
|
AFTER INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE department d
|
||||||
|
SET d.employee_count = (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM employee e
|
||||||
|
WHERE e.dept_id = d.dept_id
|
||||||
|
);
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
INSERT INTO employee
|
||||||
|
VALUES(DEFAULT, '雷昊', 60000.00, NOW(), 1, 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 3: 工资变更日志
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `salary` 字段后,将变更记录插入到一个新的日志表 `salary_log` 中,记录员工 ID、旧工资、新工资和变更时间。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DROP TABLE IF EXISTS salary_log;
|
||||||
|
CREATE TABLE salary_log(
|
||||||
|
emp_id INT,
|
||||||
|
old_salary DECIMAL(10, 2),
|
||||||
|
new_slaray DECIMAL(10, 2),
|
||||||
|
update_date DATE
|
||||||
|
);
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_update;
|
||||||
|
CREATE TRIGGER after_employee_update
|
||||||
|
BEFORE UPDATE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.salary <> OLD.salary THEN
|
||||||
|
INSERT INTO salary_log()
|
||||||
|
VALUES(NEW.emp_id, OLD.salary, NEW.salary, NOW());
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
UPDATE employee e
|
||||||
|
SET e.salary = 10
|
||||||
|
WHERE e.emp_id = 1;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 4: 删除员工时备份数据
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_delete`,在删除 `employee` 表数据之前,将被删除的员工数据插入到一个备份表 `employee_backup` 中。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE employee_backup AS
|
||||||
|
SELECT *
|
||||||
|
FROM employee
|
||||||
|
WHERE 0;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_delete;
|
||||||
|
CREATE TRIGGER before_employee_delete
|
||||||
|
BEFORE DELETE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO employee_backup()
|
||||||
|
VALUES(OLD.emp_id, OLD.emp_name, OLD.salary, OLD.hire_date, OLD.dept_id, OLD.job_id);
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DELETE FROM employee
|
||||||
|
WHERE emp_id = 20;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 5: 自动设置默认职位
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果未指定 `job_id`,则自动将其设置为 `job` 表中的默认职位(假设默认职位的 `job_id` 为 1)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.job_id IS NULL THEN
|
||||||
|
SET NEW.job_id = 1;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
INSERT INTO employee
|
||||||
|
VALUES(DEFAULT, '雷昊', 60000.00, NOW(), 1, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 6: 防止修改入职日期
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_update`,在更新 `employee` 表数据时,防止修改 `hire_date` 字段。如果尝试修改,抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_update;
|
||||||
|
CREATE TRIGGER before_employee_update
|
||||||
|
BEFORE UPDATE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.hire_date <> OLD.hire_date THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT='不允许修改用户的入职时间';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
UPDATE employee e
|
||||||
|
SET e.hire_date = '2025-3-20'
|
||||||
|
WHERE e.emp_id = 1;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 7: 自动计算工龄
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动计算员工的工龄(以年为单位),并将其存储到一个新字段 `years_of_service` 中。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER TABLE employee ADD years_of_service INT;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SET NEW.years_of_service = TIMESTAMPDIFF(YEAR,NEW.hire_date,NOW());
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
SELECT TIMESTAMPDIFF(YEAR,e.hire_date,NOW())
|
||||||
|
FROM employee e;
|
||||||
|
|
||||||
|
INSERT INTO employee
|
||||||
|
VALUES(DEFAULT, '雷昊', 60000.00, '2022-12-31', 1, 1, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 8: 防止删除部门
|
||||||
|
|
||||||
|
创建一个触发器 `before_department_delete`,在删除 `department` 表数据之前,检查该部门是否还有员工。如果有员工,阻止删除并抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_department_delete;
|
||||||
|
CREATE TRIGGER before_department_delete
|
||||||
|
BEFORE DELETE ON department
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF (SELECT COUNT(*) FROM employee e WHERE e.dept_id = OLD.dept_id) > 0 THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '该部门有员工无法删除';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DELETE FROM department
|
||||||
|
WHERE dept_id = 1;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 9: 自动更新职位工资范围
|
||||||
|
|
||||||
|
创建一个触发器 `after_job_update`,在更新 `job` 表的 `min_salary` 或 `max_salary` 字段后,自动调整 `employee` 表中相关员工的工资,使其符合新的工资范围。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_job_update;
|
||||||
|
CREATE TRIGGER after_job_update
|
||||||
|
AFTER UPDATE ON job
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE employee
|
||||||
|
SET salary = IF(salary > NEW.max_salary, NEW.max_salary, IF(salary < NEW.min_salary, min_salary, salary))
|
||||||
|
WHERE job_id = NEW.job_id;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 10: 记录部门变更
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `dept_id` 字段后,将变更记录插入到一个新的日志表 `department_change_log` 中,记录员工 ID、旧部门 ID、新部门 ID 和变更时间。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE department_change_log(
|
||||||
|
emp_id INT,
|
||||||
|
old_dept_id INT,
|
||||||
|
new_dept_id INT,
|
||||||
|
update_date DATE
|
||||||
|
);
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_update;
|
||||||
|
CREATE TRIGGER after_employee_update
|
||||||
|
AFTER UPDATE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.dept_id <> OLD.dept_id THEN
|
||||||
|
INSERT INTO department_change_log()
|
||||||
|
VALUES(NEW.emp_id, OLD.dept_id, NEW.dept_id, NOW());
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 11: 防止插入重复职位
|
||||||
|
|
||||||
|
创建一个触发器 `before_job_insert`,在插入 `job` 表数据之前,检查职位名称是否已存在。如果存在,阻止插入并抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_job_insert;
|
||||||
|
CREATE TRIGGER before_job_insert
|
||||||
|
BEFORE INSERT ON job
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF (SELECT COUNT(*) FROM job WHERE job_id = NEW.job_id) = 1 THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '职位名称已存在';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 12: 自动更新员工总数
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新一个统计表 `employee_statistics` 中的员工总数。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE employee_statistics(
|
||||||
|
marking VARCHAR(20),
|
||||||
|
num INT
|
||||||
|
);
|
||||||
|
INSERT INTO employee_statistics()
|
||||||
|
VALUES('count', 0);
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_insert;
|
||||||
|
CREATE TRIGGER after_employee_insert
|
||||||
|
AFTER INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE employee_statistics
|
||||||
|
SET num = (SELECT COUNT(*) FROM employee)
|
||||||
|
WHERE marking = 'count';
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 13: 防止修改部门所在地
|
||||||
|
|
||||||
|
创建一个触发器 `before_department_update`,在更新 `department` 表数据时,防止修改 `location` 字段。如果尝试修改,抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_department_update;
|
||||||
|
CREATE TRIGGER before_department_update
|
||||||
|
BEFORE UPDATE ON department
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.location <> OLD.location THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '无法更新部分的位置';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 14: 自动调整工资
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果工资低于职位的最低工资,则自动将其调整为最低工资。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.salary < (SELECT min_salary FROM job WHERE job_id = NEW.job_id ) THEN
|
||||||
|
SET NEW.salary = min_salary;
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 15: 记录职位变更
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `job_id` 字段后,将变更记录插入到一个新的日志表 `job_change_log` 中,记录员工 ID、旧职位 ID、新职位 ID 和变更时间。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE job_change_log(
|
||||||
|
emp_id INT,
|
||||||
|
old_job_id INT,
|
||||||
|
new_job_id INT,
|
||||||
|
update_date DATE
|
||||||
|
);
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_update;
|
||||||
|
CREATE TRIGGER after_employee_update
|
||||||
|
AFTER UPDATE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.job_id <> OLD.job_id THEN
|
||||||
|
INSERT INTO job_change_log()
|
||||||
|
VALUES(NEW.emp_id, OLD.job_id, NEW.job_id, NOW());
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 16: 防止删除职位
|
||||||
|
|
||||||
|
创建一个触发器 `before_job_delete`,在删除 `job` 表数据之前,检查该职位是否还有员工。如果有员工,阻止删除并抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_job_delete;
|
||||||
|
CREATE TRIGGER before_job_delete
|
||||||
|
BEFORE DELETE ON job
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF (SELECT COUNT(*) FROM employee WHERE job_id = OLD.job_id) > 0 THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '该职位还有员工';
|
||||||
|
END IF;
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 17: 自动更新部门平均工资
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门平均工资(假设 `department` 表新增一个字段 `avg_salary`)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_insert;
|
||||||
|
CREATE TRIGGER after_employee_insert
|
||||||
|
AFTER INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE department d
|
||||||
|
SET d.avg_salary = (SELECT AVG(e.salary) FROM employee e WHERE d.dept_id = e.dept_id)
|
||||||
|
WHERE NEW.dept_id = d.dept_id;
|
||||||
|
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 18: 防止插入未来入职日期
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,检查 `hire_date` 是否晚于当前日期。如果是,阻止插入并抛出错误。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF NEW.hire_date < CURDATE() THEN
|
||||||
|
SIGNAL SQLSTATE '45000'
|
||||||
|
SET MESSAGE_TEXT = '入职日期不得晚于当前日期';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 19: 自动生成员工编号
|
||||||
|
|
||||||
|
创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动生成一个唯一的员工编号(格式为 `EMP-年份-序号`,例如 `EMP-2023-001`),并将其存储到一个新字段 `emp_code` 中。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER TABLE employee ADD emp_code VARCHAR(30);
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS before_employee_insert;
|
||||||
|
CREATE TRIGGER before_employee_insert
|
||||||
|
BEFORE INSERT ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
SET NEW.emp_code = CONCAT('EMP-',YEAR(NOW()),'-', (LAST_INSERT_ID()+1));
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
INSERT INTO employee
|
||||||
|
VALUES(DEFAULT, '雷昊', 0, NOW(), 1, 1, NULL, NULL);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 练习题 20: 记录员工离职
|
||||||
|
|
||||||
|
创建一个触发器 `after_employee_delete`,在删除 `employee` 表数据之后,将被删除的员工信息插入到一个离职记录表 `employee_exit_log` 中,记录员工 ID、姓名、离职时间和原因(假设原因由用户输入)。
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE employee_exit_log(
|
||||||
|
emp_id INT,
|
||||||
|
emp_name VARCHAR(20),
|
||||||
|
quit_date DATE,
|
||||||
|
quit_reason VARCHAR(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
DROP TRIGGER IF EXISTS after_employee_delete;
|
||||||
|
CREATE TRIGGER after_employee_delete
|
||||||
|
AFTER DELETE ON employee
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO employee_exit_log()
|
||||||
|
VALUES(OLD.emp_id, OLD.emp_name, NOW(), NULL);
|
||||||
|
END $$
|
||||||
|
DELIMITER ;
|
||||||
|
```
|
||||||
|
|
@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
【程序设计】
|
【程序设计】
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
编写一个 C 语言函数,函数接收一个整数数组 arr 以及数组的长度 size 作为参数,使用 bool 类型返回该数组中是否存在重复的元素。在 main 函数中,输入多个正整数(输入非数字字符表示输入结束)并调用该函数,根据返回结果输出相应的提示信息。
|
编写一个 C 语言函数,函数接收一个整数数组 arr 以及数组的长度 size 作为参数,使用 bool 类型返回该数组中是否存在重复的元素。在 main 函数中,输入多个正整数(输入非数字字符表示输入结束)并调用该函数,根据返回结果输出相应的提示信息。
|
||||||
示例:
|
示例:
|
||||||
【请输入多个整数(输入非数字字符结束输入):】1 2 3 4 5 5 6 a
|
【请输入多个整数(输入非数字字符结束输入):】1 2 3 4 5 5 6 a
|
||||||
数组中存在重复元素。
|
数组中存在重复元素。
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在
|
注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在
|
||||||
Program-End之间填入若干语句。
|
Program-End之间填入若干语句。
|
||||||
不要删除标志否则不得分。
|
不要删除标志否则不得分。
|
||||||
不要修改或删除Program-End之外的内容否则不得分。
|
不要修改或删除Program-End之外的内容否则不得分。
|
||||||
----------------------------------------------------------------------*/
|
----------------------------------------------------------------------*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -36,12 +36,12 @@ int main() {
|
|||||||
int *arr = (int *)malloc(capacity * sizeof(int));
|
int *arr = (int *)malloc(capacity * sizeof(int));
|
||||||
|
|
||||||
if (arr == NULL) {
|
if (arr == NULL) {
|
||||||
printf("内存分配失败!\n");
|
printf("内存分配失败!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int num;
|
int num;
|
||||||
printf("【请输入多个整数(输入非数字字符结束输入):】");
|
printf("【请输入多个整数(输入非数字字符结束输入):】");
|
||||||
|
|
||||||
while (scanf("%d", &num) == 1) {
|
while (scanf("%d", &num) == 1) {
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ int main() {
|
|||||||
arr = (int *)realloc(arr, capacity * sizeof(int));
|
arr = (int *)realloc(arr, capacity * sizeof(int));
|
||||||
|
|
||||||
if (arr == NULL) {
|
if (arr == NULL) {
|
||||||
printf("内存分配失败!\n");
|
printf("内存分配失败!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,9 +62,9 @@ int main() {
|
|||||||
|
|
||||||
|
|
||||||
if (hasDuplicates(arr, size)) {
|
if (hasDuplicates(arr, size)) {
|
||||||
printf("数组中存在重复元素。\n");
|
printf("数组中存在重复元素。\n");
|
||||||
} else {
|
} else {
|
||||||
printf("数组中不存在重复元素。\n");
|
printf("数组中不存在重复元素。\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
【程序设计】
|
【程序设计】
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
现在有一位赛车手要驾驶一台电动摩托车去完成多段赛程。这台电动摩托车的电池电量存储
|
现在有一位赛车手要驾驶一台电动摩托车去完成多段赛程。这台电动摩托车的电池电量存储
|
||||||
上限是 100 度电哦,它有一个标称的平均电耗,也就是每行驶 100 公里,就会消耗 10度
|
上限是 100 度电哦,它有一个标称的平均电耗,也就是每行驶 100 公里,就会消耗 10度
|
||||||
电。这里有个很重要的前提条件要大家牢记呀,每一段赛程的距离都是小于 600 公里的哦,
|
电。这里有个很重要的前提条件要大家牢记呀,每一段赛程的距离都是小于 600 公里的哦,
|
||||||
并且每次出发的时候,电动摩托车的电池都是充满电的状态呢。还有一个关键的规则得注意
|
并且每次出发的时候,电动摩托车的电池都是充满电的状态呢。还有一个关键的规则得注意
|
||||||
哦,如果电动摩托车到达某个地点之后,赛车手查看发现电池内剩余的电量低于电池总电量
|
哦,如果电动摩托车到达某个地点之后,赛车手查看发现电池内剩余的电量低于电池总电量
|
||||||
的 10%(也就是 100×10% = 10 度电或者更少啦),那这个时候就必须得在这个地方给电
|
的 10%(也就是 100×10% = 10 度电或者更少啦),那这个时候就必须得在这个地方给电
|
||||||
动摩托车充电了呢,请帮忙计算一下,这名驾驶员在赛程中的哪几段赛程前是需要充电的。
|
动摩托车充电了呢,请帮忙计算一下,这名驾驶员在赛程中的哪几段赛程前是需要充电的。
|
||||||
|
|
||||||
示例1:
|
示例1:
|
||||||
【请输入赛程段数:】
|
【请输入赛程段数:】
|
||||||
5
|
5
|
||||||
【请输入各段赛程距离,单位公里:】
|
【请输入各段赛程距离,单位公里:】
|
||||||
380 200 390 400 300
|
380 200 390 400 300
|
||||||
【需要在以下几段赛程前充电:】
|
【需要在以下几段赛程前充电:】
|
||||||
第 3 段赛程前
|
第 3 段赛程前
|
||||||
第 5 段赛程前
|
第 5 段赛程前
|
||||||
|
|
||||||
示例2:
|
示例2:
|
||||||
【请输入赛程段数:】
|
【请输入赛程段数:】
|
||||||
4
|
4
|
||||||
【请输入各段赛程距离,单位公里:】
|
【请输入各段赛程距离,单位公里:】
|
||||||
190 140 110 80
|
190 140 110 80
|
||||||
无需充电。
|
无需充电。
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在
|
注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在
|
||||||
Program-End之间填入若干语句。
|
Program-End之间填入若干语句。
|
||||||
不要删除标志否则不得分。
|
不要删除标志否则不得分。
|
||||||
不要修改或删除Program-End之外的内容否则不得分。
|
不要修改或删除Program-End之外的内容否则不得分。
|
||||||
----------------------------------------------------------------------*/
|
----------------------------------------------------------------------*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h> // 引入stdlib.h用于动态内存分配相关操作
|
#include <stdlib.h> // 引入stdlib.h用于动态内存分配相关操作
|
||||||
|
|
||||||
#define TANK_CAPACITY 100 // 电池总容量(单位:度)
|
#define TANK_CAPACITY 100 // 电池总容量(单位:度)
|
||||||
#define LOW_FUEL_LIMIT (0.10 * TANK_CAPACITY) // 低电量阈值(10%)
|
#define LOW_FUEL_LIMIT (0.10 * TANK_CAPACITY) // 低电量阈值(10%)
|
||||||
#define AVG_CONSUMPTION_PER_100KM 10 // 平均电耗(单位:度/百公里)
|
#define AVG_CONSUMPTION_PER_100KM 10 // 平均电耗(单位:度/百公里)
|
||||||
#define FUEL_CONSUMPTION_PER_KM (AVG_CONSUMPTION_PER_100KM / 100.0) // 每公里电耗(单位:度/公里)
|
#define FUEL_CONSUMPTION_PER_KM (AVG_CONSUMPTION_PER_100KM / 100.0) // 每公里电耗(单位:度/公里)
|
||||||
|
|
||||||
int checkRefuelStops(int trips[], int count, int results[]) {
|
int checkRefuelStops(int trips[], int count, int results[]) {
|
||||||
int refuel_count = 0;
|
int refuel_count = 0;
|
||||||
@ -56,17 +56,17 @@ int checkRefuelStops(int trips[], int count, int results[]) {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int num_trips;
|
int num_trips;
|
||||||
printf("【请输入赛程段数:】\n");
|
printf("【请输入赛程段数:】\n");
|
||||||
scanf("%d", &num_trips);
|
scanf("%d", &num_trips);
|
||||||
|
|
||||||
|
|
||||||
int *trips = (int *)malloc(num_trips * sizeof(int));
|
int *trips = (int *)malloc(num_trips * sizeof(int));
|
||||||
if (trips == NULL) {
|
if (trips == NULL) {
|
||||||
printf("内存分配失败!\n");
|
printf("内存分配失败!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("【请输入各段赛程距离,单位公里:】\n");
|
printf("【请输入各段赛程距离,单位公里:】\n");
|
||||||
for (int i = 0; i < num_trips; ++i) {
|
for (int i = 0; i < num_trips; ++i) {
|
||||||
scanf("%d", &trips[i]);
|
scanf("%d", &trips[i]);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ int main() {
|
|||||||
|
|
||||||
int *results = (int *)malloc(num_trips * sizeof(int));
|
int *results = (int *)malloc(num_trips * sizeof(int));
|
||||||
if (results == NULL) {
|
if (results == NULL) {
|
||||||
printf("内存分配失败!\n");
|
printf("内存分配失败!\n");
|
||||||
free(trips);
|
free(trips);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -82,12 +82,12 @@ int main() {
|
|||||||
int refuel_count = checkRefuelStops(trips, num_trips, results);
|
int refuel_count = checkRefuelStops(trips, num_trips, results);
|
||||||
|
|
||||||
if (refuel_count > 0) {
|
if (refuel_count > 0) {
|
||||||
printf("【需要在以下几段赛程前充电:】\n");
|
printf("【需要在以下几段赛程前充电:】\n");
|
||||||
for (int i = 0; i < refuel_count; i++) {
|
for (int i = 0; i < refuel_count; i++) {
|
||||||
printf("第 %d 段赛程前\n", results[i]);
|
printf("第 %d 段赛程前\n", results[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("无需充电。\n");
|
printf("无需充电。\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(trips);
|
free(trips);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user