-- ==============================================
-- 优化核心:
-- 1. 全程关闭外键检查,建表完成后统一开启
-- 2. 给核心字段加索引,避免全表扫描
-- 3. 显式命名外键,避免冲突
-- 4. 简化触发器逻辑,减少重复计算
-- ==============================================
-- 1. 基础配置(高性能关键)
CREATE DATABASE IF NOT EXISTS company_hrms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SET FOREIGN_KEY_CHECKS=0; -- 全程关闭外键检查,提速+避错
SET SQL_MODE='NO_ENGINE_SUBSTITUTION'; -- 强制InnoDB引擎
USE company_hrms;
-- 2. 清空旧表(避免残留数据/结构干扰)
DROP TABLE IF EXISTS personnel_change;
DROP TABLE IF EXISTS salary;
DROP TABLE IF EXISTS attendance;
DROP TABLE IF EXISTS sys_config;
DROP TABLE IF EXISTS sys_user;
DROP TABLE IF EXISTS employee;
DROP TABLE IF EXISTS department;
-- 3. 建表(按「无依赖→有依赖」顺序,加优化索引)
-- ----------------------------
-- 部门信息表(无依赖,最先建)
-- ----------------------------
CREATE TABLE `department` (
`dept_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门ID(主键)',
`dept_name` varchar(50) NOT NULL COMMENT '部门名称',
`dept_code` varchar(20) NOT NULL COMMENT '部门编号',
`dept_duty` varchar(200) DEFAULT NULL COMMENT '部门职责',
`parent_dept_id` int(11) DEFAULT NULL COMMENT '上级部门ID',
PRIMARY KEY (`dept_id`),
UNIQUE KEY `idx_dept_code` (`dept_code`),
KEY `idx_parent_dept` (`parent_dept_id`),
CONSTRAINT `fk_dept_parent` FOREIGN KEY (`parent_dept_id`) REFERENCES `department` (`dept_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门信息表';
-- ----------------------------
-- 员工基本信息表(依赖department)
-- ----------------------------
CREATE TABLE `employee` (
`emp_id` varchar(20) NOT NULL COMMENT '员工工号(主键)',
`emp_name` varchar(30) NOT NULL COMMENT '员工姓名',
`gender` enum('男','女') DEFAULT NULL COMMENT '性别',
`birth_date` date DEFAULT NULL COMMENT '出生日期',
`entry_date` date NOT NULL COMMENT '入职时间',
`title` varchar(30) DEFAULT NULL COMMENT '职称',
`contact` varchar(20) DEFAULT NULL COMMENT '联系方式',
`dept_id` int(11) NOT NULL COMMENT '所属部门ID',
`position` varchar(30) DEFAULT NULL COMMENT '岗位',
`work_perf` text DEFAULT NULL COMMENT '工作成绩',
`emp_status` enum('在职','离职','退休') DEFAULT '在职' COMMENT '员工状态',
PRIMARY KEY (`emp_id`),
KEY `idx_emp_dept` (`dept_id`),
KEY `idx_emp_status` (`emp_status`), -- 优化人事变动查询
CONSTRAINT `fk_emp_dept` FOREIGN KEY (`dept_id`) REFERENCES `department` (`dept_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工基本信息表';
-- ----------------------------
-- 系统用户权限表(依赖department+employee)
-- ----------------------------
-- 创建sys_user表(兼容MySQL 5.5+所有版本)
CREATE TABLE `sys_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID(主键)',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '加密密码(MD5)',
`permission` enum('1','2','3','4') NOT NULL COMMENT '权限:1-管理员/2-人事/3-部门领导/4-普通员工',
`dept_id` int(11) DEFAULT NULL COMMENT '所属部门ID',
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', -- 改用TIMESTAMP兼容低版本
`emp_id` varchar(20) DEFAULT NULL COMMENT '关联员工工号',
PRIMARY KEY (`user_id`),
UNIQUE KEY `idx_username` (`username`),
KEY `idx_user_dept` (`dept_id`),
KEY `idx_user_emp` (`emp_id`),
CONSTRAINT `fk_user_dept` FOREIGN KEY (`dept_id`) REFERENCES `department` (`dept_id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `fk_user_emp` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`emp_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户权限表';
-- ----------------------------
-- 系统配置表(依赖sys_user)
-- ----------------------------
CREATE TABLE `sys_config` (
`config_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '配置ID(主键)',
`sys_name` varchar(50) DEFAULT '公司人事管理系统' COMMENT '系统名称',
`sys_code` varchar(20) DEFAULT 'HRMS_V1.0' COMMENT '系统编号',
`backup_time` datetime DEFAULT NULL COMMENT '备份时间',
`restore_time` datetime DEFAULT NULL COMMENT '恢复时间',
`backup_path` varchar(200) DEFAULT NULL COMMENT '备份路径',
`operator_id` int(11) DEFAULT NULL COMMENT '操作人ID',
PRIMARY KEY (`config_id`),
UNIQUE KEY `idx_sys_code` (`sys_code`),
KEY `idx_config_operator` (`operator_id`),
CONSTRAINT `fk_config_user` FOREIGN KEY (`operator_id`) REFERENCES `sys_user` (`user_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
-- ----------------------------
-- 员工考勤记录表(依赖employee,加高性能索引)
-- ----------------------------
CREATE TABLE `attendance` (
`att_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '考勤ID(主键)',
`emp_id` varchar(20) NOT NULL COMMENT '员工工号',
`att_date` date NOT NULL COMMENT '考勤日期',
`att_status` enum('正常','迟到','早退','事假','旷工') NOT NULL COMMENT '考勤状态',
`late_duration` int(11) DEFAULT 0 COMMENT '迟到时长(分钟)',
`early_duration` int(11) DEFAULT 0 COMMENT '早退时长(分钟)',
`leave_days` decimal(2,1) DEFAULT 0.0 COMMENT '事假天数',
`remarks` text DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`att_id`),
UNIQUE KEY `idx_emp_date` (`emp_id`,`att_date`), -- 唯一约束+索引
KEY `idx_att_status` (`att_status`), -- 优化触发器统计
KEY `idx_att_date` (`att_date`), -- 优化按月统计
CONSTRAINT `fk_att_emp` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`emp_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工考勤记录表';
-- ----------------------------
-- 员工工资信息表(依赖employee)
-- ----------------------------
CREATE TABLE `salary` (
`salary_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '工资记录ID(主键)',
`emp_id` varchar(20) NOT NULL COMMENT '员工工号',
`year` int(11) NOT NULL COMMENT '年份',
`month` int(11) NOT NULL COMMENT '月份',
`base_salary` decimal(10,2) NOT NULL COMMENT '基本工资',
`perf_salary` decimal(10,2) DEFAULT 0.00 COMMENT '绩效工资',
`attendance_bonus` decimal(10,2) DEFAULT 0.00 COMMENT '考勤奖金',
`deductions` decimal(10,2) DEFAULT 0.00 COMMENT '扣除项',
`actual_salary` decimal(10,2) DEFAULT NULL COMMENT '实发工资(自动计算)',
`pay_status` enum('未发','已发') DEFAULT '未发' COMMENT '发放状态',
PRIMARY KEY (`salary_id`),
UNIQUE KEY `idx_emp_year_month` (`emp_id`,`year`,`month`), -- 唯一约束+索引
KEY `idx_salary_pay` (`pay_status`),
CONSTRAINT `fk_salary_emp` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`emp_id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工工资信息表';
-- ----------------------------
-- 员工人事变动记录表(依赖employee+sys_user+department)
-- ----------------------------
-- 创建人事变动表(兼容MySQL 5.5+所有版本)
CREATE TABLE `personnel_change` (
`change_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '变动记录ID(主键)',
`emp_id` varchar(20) NOT NULL COMMENT '员工工号',
`change_type` enum('调动','辞职','退休') NOT NULL COMMENT '变动类型',
`apply_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '申请时间', -- 改用TIMESTAMP兼容低版本
`approver_id` int(11) DEFAULT NULL COMMENT '审批人ID',
`approve_status` enum('待审批','通过','驳回') DEFAULT '待审批' COMMENT '审批状态',
`approve_opinion` text DEFAULT NULL COMMENT '审批意见',
`effective_time` date DEFAULT NULL COMMENT '变动生效时间',
`original_dept_id` int(11) NOT NULL COMMENT '原部门ID',
`new_dept_id` int(11) DEFAULT NULL COMMENT '新部门ID',
PRIMARY KEY (`change_id`),
KEY `idx_change_emp` (`emp_id`),
KEY `idx_change_approve` (`approver_id`),
KEY `idx_change_status` (`approve_status`),
KEY `idx_change_original_dept` (`original_dept_id`),
KEY `idx_change_new_dept` (`new_dept_id`),
CONSTRAINT `fk_change_emp` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`emp_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_change_approver` FOREIGN KEY (`approver_id`) REFERENCES `sys_user` (`user_id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `fk_change_original_dept` FOREIGN KEY (`original_dept_id`) REFERENCES `department` (`dept_id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_change_new_dept` FOREIGN KEY (`new_dept_id`) REFERENCES `department` (`dept_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工人事变动记录表';
-- 4. 初始化数据(批量插入,提速)
-- ----------------------------
-- 部门数据
INSERT INTO `department` (`dept_id`, `dept_name`, `dept_code`, `dept_duty`, `parent_dept_id`)
VALUES
(1, '总经办', 'ZBJ001', '公司整体运营管理、高层决策', NULL),
(2, '人事部', 'RSB001', '员工人事管理、招聘、变动审批', 1),
(3, '技术部', 'JSB001', '技术研发、系统维护、项目交付', 1),
(4, '财务部', 'CWB001', '工资核算、财务管控、成本统计', 1);
-- ----------------------------
-- 员工数据
INSERT INTO `employee` (`emp_id`, `emp_name`, `gender`, `birth_date`, `entry_date`, `title`, `contact`, `dept_id`, `position`, `work_perf`, `emp_status`)
VALUES
('001', '朱俊晖', '男', '2005-03-10', '2020-03-15', '工程师', '13800138001', 3, '后端开发', '负责系统模块开发', '在职'),
('002', '杨阳', '男', '1998-10-02', '2019-01-08', '主管', '13800138002', 2, '人事主管', '负责人事变动、考勤管理', '在职'),
('003', '孙亚飞', '男', '2006-07-07', '2021-07-22', '工程师', '13800138003', 3, '前端开发', '负责页面开发与调试', '在职'),
('004', '邵吉浩', '男', '1985-02-18', '2018-05-10', '总经理', '13800138004', 1, '总经理', '公司整体运营决策', '在职'),
('005', '杨振兴', '男', '1999-08-20', '2018-08-10', '部门经理', '13800138005', 3, '技术部领导', '技术部团队管理、任务分配', '在职');
-- ----------------------------
-- 系统用户数据
INSERT INTO `sys_user` (`user_id`, `username`, `password`, `permission`, `dept_id`, `create_time`, `emp_id`)
VALUES
(1, 'shaojihao', 'e10adc3949ba59abbe56e057f20f883e', '1', 1, '2025-12-02 10:48:40', '004'),
(2, 'yangyang', 'e10adc3949ba59abbe56e057f20f883e', '2', 2, '2025-12-02 10:48:40', '002'),
(3, 'yangzhenxing', 'e10adc3949ba59abbe56e057f20f883e', '3', 3, '2025-12-02 10:48:40', '005'),
(4, 'sunyafei', 'e10adc3949ba59abbe56e057f20f883e', '4', 3, '2025-12-02 10:48:40', '003'),
(5, 'zhujunhui', 'e10adc3949ba59abbe56e057f20f883e', '4', 3, '2025-12-02 10:48:40', '001');
-- ----------------------------
-- 系统配置数据
INSERT INTO `sys_config` (`config_id`, `sys_name`, `sys_code`, `backup_time`, `restore_time`, `backup_path`, `operator_id`)
VALUES
(1, '公司人事管理系统', 'HRMS_V1.0', '2025-11-01 00:00:00', NULL, 'C:\\Users\\lenovo\\Desktop\\强盛集团', 1);
-- ----------------------------
-- 考勤数据
INSERT INTO `attendance` (`att_id`, `emp_id`, `att_date`, `att_status`, `late_duration`, `early_duration`, `leave_days`, `remarks`)
VALUES
(1, '005', '2025-11-27', '早退', 0, 30, 0.0, '早退30分钟扣除50元'),
(2, '001', '2025-11-27', '正常', 0, 0, 0.0, ''),
(3, '002', '2025-11-27', '正常', 0, 0, 0.0, ''),
(4, '003', '2025-11-27', '正常', 0, 0, 0.0, ''),
(5, '004', '2025-11-27', '正常', 0, 0, 0.0, ''),
(6, '003', '2025-11-28', '旷工', 0, 0, 1.0, '旷工一天扣除200元'),
(7, '002', '2025-11-28', '事假', 0, 0, 1.0, '事假一天扣除200元'),
(8, '001', '2025-11-28', '正常', 0, 0, 0.0, ''),
(9, '005', '2025-11-28', '正常', 0, 0, 0.0, ''),
(10, '004', '2025-11-28', '正常', 0, 0, 0.0, ''),
(11, '001', '2025-11-29', '迟到', 10, 0, 0.0, '扣除全勤50元'),
(12, '002', '2025-11-29', '正常', 0, 0, 0.0, ''),
(13, '003', '2025-11-29', '正常', 0, 0, 0.0, ''),
(14, '004', '2025-11-29', '正常', 0, 0, 0.0, ''),
(15, '005', '2025-11-29', '正常', 0, 0, 0.0, '');
-- ----------------------------
-- 工资数据
INSERT INTO `salary` (`salary_id`, `emp_id`, `year`, `month`, `base_salary`, `perf_salary`, `attendance_bonus`, `deductions`, `actual_salary`, `pay_status`)
VALUES
(1, '001', 2025, 11, 6000.00, 1000.00, 800.00, 50.00, 6750.00, '已发'),
(2, '002', 2025, 11, 8000.00, 2000.00, 1000.00, 200.00, 10800.00, '已发'),
(3, '003', 2025, 11, 6000.00, 1000.00, 800.00, 200.00, 7600.00, '已发'),
(4, '004', 2025, 11, 15000.00, 2000.00, 1000.00, 0.00, 18000.00, '已发'),
(5, '005', 2025, 11, 10000.00, 2000.00, 1000.00, 50.00, 12950.00, '已发');
-- ----------------------------
-- 人事变动数据
INSERT INTO `personnel_change` (`change_id`, `emp_id`, `change_type`, `apply_time`, `approver_id`, `approve_status`, `approve_opinion`, `effective_time`, `original_dept_id`, `new_dept_id`)
VALUES
(1, '003', '调动', '2025-11-28 09:00:00', 1, '通过', '通过', '2025-12-01', 3, 2),
(2, '001', '辞职', '2025-11-29 14:30:00', 2, '待审批', '', NULL, 3, NULL);
-- 5. 重建外键检查(数据插入完成后开启)
SET FOREIGN_KEY_CHECKS=1;
-- 6. 触发器(简化逻辑,复用计算逻辑)
DELIMITER $$
-- 通用函数:计算考勤奖金和扣除项(避免触发器重复代码)
CREATE FUNCTION calc_attendance_bonus_deduct(p_emp_id VARCHAR(20), p_year INT, p_month INT)
RETURNS VARCHAR(50)
BEGIN
-- 变量声明并初始化,避免NULL干扰
DECLARE bonus DECIMAL(10,2) DEFAULT 0.00;
DECLARE deduct DECIMAL(10,2) DEFAULT 0.00;
DECLARE total_late INT DEFAULT 0;
DECLARE total_early INT DEFAULT 0;
DECLARE total_absent DECIMAL(2,1) DEFAULT 0.0;
DECLARE total_leave DECIMAL(2,1) DEFAULT 0.0;
-- 简化统计语法,适配低版本MySQL
SELECT
COUNT(IF(att_status='迟到',1,NULL)),
COUNT(IF(att_status='早退',1,NULL)),
IFNULL(SUM(IF(att_status='旷工',leave_days,0)),0),
IFNULL(SUM(IF(att_status='事假',leave_days,0)),0)
INTO total_late, total_early, total_absent, total_leave
FROM attendance
WHERE emp_id = p_emp_id
AND YEAR(att_date) = p_year
AND MONTH(att_date) = p_month;
-- 计算奖金和扣除项
SET bonus = IF(total_late + total_early + total_absent + total_leave = 0, 1000.00, 0.00);
SET deduct = (total_late + total_early) * 50 + total_absent * 200 + total_leave * 100;
-- 返回拼接结果
RETURN CONCAT(bonus, '|', deduct);
END ;;
-- 触发器1:插入考勤后更新工资
CREATE TRIGGER after_attendance_insert
AFTER INSERT ON attendance
FOR EACH ROW
BEGIN
-- 声明变量并初始化,避免NULL干扰
DECLARE bonus DECIMAL(10,2) DEFAULT 0.00;
DECLARE deduct DECIMAL(10,2) DEFAULT 0.00;
DECLARE total_late INT DEFAULT 0;
DECLARE total_early INT DEFAULT 0;
DECLARE total_absent DECIMAL(2,1) DEFAULT 0.0;
DECLARE total_leave DECIMAL(2,1) DEFAULT 0.0;
DECLARE p_year INT;
DECLARE p_month INT;
-- 拆分年月赋值,避免嵌套函数报错
SET p_year = YEAR(NEW.att_date);
SET p_month = MONTH(NEW.att_date);
-- 极简统计语法,适配所有MySQL版本
SELECT
COUNT(IF(att_status='迟到',1,NULL)), -- 迟到次数
COUNT(IF(att_status='早退',1,NULL)), -- 早退次数
IFNULL(SUM(IF(att_status='旷工',leave_days,0)),0), -- 旷工天数
IFNULL(SUM(IF(att_status='事假',leave_days,0)),0) -- 事假天数
INTO total_late, total_early, total_absent, total_leave
FROM attendance
WHERE emp_id = NEW.emp_id
AND YEAR(att_date) = p_year
AND MONTH(att_date) = p_month;
-- 计算全勤奖和扣除项
SET bonus = IF(total_late + total_early + total_absent + total_leave = 0, 1000.00, 0.00);
SET deduct = (total_late + total_early) * 50 + total_absent * 200 + total_leave * 100;
-- 更新工资表
UPDATE salary
SET
attendance_bonus = bonus,
deductions = deduct,
actual_salary = base_salary + perf_salary + bonus - deduct
WHERE emp_id = NEW.emp_id AND year = p_year AND month = p_month;
END ;; -- 触发器结束符匹配DELIMITER设置
-- 触发器2:更新考勤后更新工资
CREATE TRIGGER after_attendance_update
AFTER UPDATE ON attendance
FOR EACH ROW
BEGIN
-- 声明变量并初始化,避免NULL干扰
DECLARE bonus DECIMAL(10,2) DEFAULT 0.00;
DECLARE deduct DECIMAL(10,2) DEFAULT 0.00;
DECLARE total_late INT DEFAULT 0;
DECLARE total_early INT DEFAULT 0;
DECLARE total_absent DECIMAL(2,1) DEFAULT 0.0;
DECLARE total_leave DECIMAL(2,1) DEFAULT 0.0;
DECLARE p_year INT;
DECLARE p_month INT;
-- 拆分年月赋值,避免嵌套函数报错
SET p_year = YEAR(NEW.att_date);
SET p_month = MONTH(NEW.att_date);
-- 极简统计语法,适配所有MySQL版本
SELECT
COUNT(IF(att_status='迟到',1,NULL)),
COUNT(IF(att_status='早退',1,NULL)),
IFNULL(SUM(IF(att_status='旷工',leave_days,0)),0),
IFNULL(SUM(IF(att_status='事假',leave_days,0)),0)
INTO total_late, total_early, total_absent, total_leave
FROM attendance
WHERE emp_id = NEW.emp_id
AND YEAR(att_date) = p_year
AND MONTH(att_date) = p_month;
-- 计算全勤奖和扣除项
SET bonus = IF(total_late + total_early + total_absent + total_leave = 0, 1000.00, 0.00);
SET deduct = (total_late + total_early) * 50 + total_absent * 200 + total_leave * 100;
-- 更新工资表
UPDATE salary
SET
attendance_bonus = bonus,
deductions = deduct,
actual_salary = base_salary + perf_salary + bonus - deduct
WHERE emp_id = NEW.emp_id AND year = p_year AND month = p_month;
END ;;
-- 触发器3:人事变动审批通过后更新员工信息
CREATE TRIGGER after_personnel_change_update
AFTER UPDATE ON personnel_change
FOR EACH ROW
BEGIN
-- 调动通过:更新部门
IF NEW.approve_status = '通过' AND NEW.change_type = '调动' THEN
UPDATE employee
SET dept_id = NEW.new_dept_id
WHERE emp_id = NEW.emp_id;
END IF;
-- 辞职/退休通过:更新状态
IF NEW.approve_status = '通过' THEN
IF NEW.change_type = '辞职' THEN
UPDATE employee SET emp_status = '离职' WHERE emp_id = NEW.emp_id;
ELSEIF NEW.change_type = '退休' THEN
UPDATE employee SET emp_status = '退休' WHERE emp_id = NEW.emp_id;
END IF;
END IF;
END ;;
-- 7. 存储过程(优化查询逻辑,加LIMIT防大数据量)
DELIMITER $$
-- 存储过程1:查询员工工资
CREATE PROCEDURE query_employee_salary(
IN p_emp_id VARCHAR(20),
IN p_year INT,
IN p_month INT
)
BEGIN
SELECT
emp_id AS 员工工号,
CONCAT(year, '年', month, '月') AS 薪资月份,
base_salary AS 基本工资,
perf_salary AS 绩效工资,
attendance_bonus AS 考勤奖金,
deductions AS 扣除项,
actual_salary AS 实发工资,
pay_status AS 发放状态
FROM salary
WHERE emp_id = p_emp_id
AND (p_year IS NULL OR year = p_year)
AND (p_month IS NULL OR month = p_month)
LIMIT 100; -- 防全表扫描
END ;;
-- 存储过程2:部门工资汇总(优化JOIN顺序)
CREATE PROCEDURE query_dept_salary_summary(
IN p_dept_id INT,
IN p_year INT,
IN p_month INT
)
BEGIN
SELECT
d.dept_name AS 部门名称,
e.emp_id AS 员工工号,
e.emp_name AS 员工姓名,
s.base_salary + s.perf_salary + s.attendance_bonus - s.deductions AS 实发工资
FROM department d
JOIN employee e ON d.dept_id = e.dept_id -- 小表驱动大表
JOIN salary s ON e.emp_id = s.emp_id
WHERE d.dept_id = p_dept_id
AND s.year = p_year
AND s.month = p_month
ORDER BY 实发工资 DESC
LIMIT 1000;
END ;;
-- 存储过程3:系统备份
CREATE PROCEDURE backup_system(
IN p_operator_id INT,
IN p_backup_path VARCHAR(200)
)
BEGIN
INSERT INTO sys_config (sys_name, sys_code, backup_time, backup_path, operator_id)
VALUES ('公司人事管理系统', 'HRMS_V1.0', NOW(), p_backup_path, p_operator_id)
ON DUPLICATE KEY UPDATE
backup_time = NOW(),
backup_path = p_backup_path,
operator_id = p_operator_id;
END ;;
-- 存储过程4:提交人事变动申请
CREATE PROCEDURE submit_personnel_change(
IN p_emp_id VARCHAR(20),
IN p_change_type ENUM('调动','辞职','退休'),
IN p_original_dept_id INT,
IN p_new_dept_id INT,
IN p_approver_id INT
)
BEGIN
INSERT INTO personnel_change (emp_id, change_type, original_dept_id, new_dept_id, approver_id)
VALUES (p_emp_id, p_change_type, p_original_dept_id, p_new_dept_id, p_approver_id);
END ;;
-- ==============================================
-- 第二步:功能测试(增强兼容性+完善验证+清晰输出)
-- ==============================================
-- 测试1:查询003员工2025年11月工资明细(优化点:自动匹配字符集,避免手动指定COLLATE)
-- 核心:删除硬编码的COLLATE,利用数据库默认字符集适配,避免1253错误
CALL query_employee_salary('003', 2025, 11);
-- 测试1补充:验证查询结果(输出明细+总数,便于核对)
SELECT '【测试1】003员工2025年11月工资明细' AS 测试项;
SELECT * FROM (
SELECT
emp_id AS 员工工号,
CONCAT(year, '年', month, '月') AS 薪资月份,
base_salary AS 基本工资,
perf_salary AS 绩效工资,
attendance_bonus AS 考勤奖金,
deductions AS 扣除项,
actual_salary AS 实发工资,
pay_status AS 发放状态
FROM salary
WHERE emp_id = '003' AND year = 2025 AND month = 11
) t1 UNION ALL
SELECT '合计', '', '', '', '', '', '', '';
-- 测试2:查询3号部门2025年11月工资汇总(优化点:增加部门名称、空值处理、表头说明)
CALL query_dept_salary_summary(3, 2025, 11);
-- 测试2补充:验证汇总结果(统计人数+总工资,便于核对)
SELECT '【测试2】3号部门2025年11月工资汇总' AS 测试项;
SELECT
d.dept_name AS 部门名称,
COUNT(e.emp_id) AS 员工人数,
SUM(s.base_salary + s.perf_salary + s.attendance_bonus - s.deductions) AS 部门总实发工资
FROM department d
JOIN employee e ON d.dept_id = e.dept_id
JOIN salary s ON e.emp_id = s.emp_id
WHERE d.dept_id = 3 AND s.year = 2025 AND s.month = 11
GROUP BY d.dept_name;
-- 测试3:执行系统备份(优化点:增加备份记录验证+路径兼容性)
-- 核心:备份后查询sys_config表,确认备份记录已写入
CALL backup_system(1, 'C:/Users/lenovo/Desktop/backup_20251204');
SELECT '【测试3】系统备份执行结果' AS 测试项;
SELECT
config_id AS 配置ID,
sys_name AS 系统名称,
backup_time AS 备份时间,
backup_path AS 备份路径,
(SELECT emp_name FROM employee WHERE emp_id = (SELECT emp_id FROM sys_user WHERE user_id = operator_id)) AS 操作人
FROM sys_config
WHERE backup_path = 'C:/Users/lenovo/Desktop/backup_20251204';
-- ==============================================
-- 第三步:全量验证(新增关键表数据校验,确保初始化完整)
-- ==============================================
SELECT '【全量验证】核心表数据完整性检查' AS 验证项;
-- 1. 部门表数据校验
SELECT '部门表' AS 表名, COUNT(*) AS 记录数 FROM department WHERE dept_id IN (1,2,3,4) UNION ALL
-- 2. 员工表数据校验
SELECT '员工表' AS 表名, COUNT(*) AS 记录数 FROM employee WHERE emp_id IN ('001','002','003','004','005') UNION ALL
-- 3. 考勤表数据校验
SELECT '考勤表' AS 表名, COUNT(*) AS 记录数 FROM attendance WHERE YEAR(att_date) = 2025 AND MONTH(att_date) = 11 UNION ALL
-- 4. 工资表数据校验
SELECT '工资表' AS 表名, COUNT(*) AS 记录数 FROM salary WHERE year = 2025 AND month = 11 UNION ALL
-- 5. 人事变动表数据校验
SELECT '人事变动表' AS 表名, COUNT(*) AS 记录数 FROM personnel_change;
-- ==============================================
-- 最终提示(增强可读性,区分成功/失败场景)
-- ==============================================
SET @total_error = 0;
-- 检查关键表是否有数据
SELECT COUNT(*) INTO @total_error FROM department WHERE dept_id IS NULL;
SELECT COUNT(*) INTO @total_error FROM employee WHERE emp_id IS NULL;
SELECT COUNT(*) INTO @total_error FROM salary WHERE actual_salary IS NULL AND year = 2025 AND month = 11;
IF @total_error = 0 THEN
SELECT '✅ 数据库创建成功!所有模块优化完成,测试用例执行通过,数据完整性验证通过!' AS 最终提示;
ELSE
SELECT '❌ 数据库创建完成,但部分数据缺失!请检查初始化脚本或测试数据!' AS 最终提示;
END IF;
最新发布