如何实现MySQL存储过程支持传入多个员工姓氏参数?
支持多员工姓氏参数的MySQL存储过程修改方案
方案1:使用逗号分隔字符串传参(兼容所有MySQL版本)
这种方式适配所有MySQL版本,只需将多个员工姓氏用逗号拼接成字符串传入,内部通过字符串函数匹配符合条件的员工。
以下是修改后的UpdateEmployeeSalary存储过程代码:
DELIMITER // CREATE PROCEDURE UpdateEmployeeSalary(IN p_last_names VARCHAR(1000)) BEGIN -- 1. 创建更新前的临时表,存储指定员工薪资数据 CREATE TEMPORARY TABLE IF NOT EXISTS temp_salary_before ( employee_id INT, last_name VARCHAR(50), salary DECIMAL(10,2) ); INSERT INTO temp_salary_before SELECT employee_id, last_name, salary FROM employees WHERE FIND_IN_SET(last_name, p_last_names) > 0; -- 2. 对指定员工薪资上调2% UPDATE employees SET salary = salary * 1.02 WHERE FIND_IN_SET(last_name, p_last_names) > 0; -- 3. 创建更新后的临时表,存储指定员工薪资数据 CREATE TEMPORARY TABLE IF NOT EXISTS temp_salary_after ( employee_id INT, last_name VARCHAR(50), salary DECIMAL(10,2) ); INSERT INTO temp_salary_after SELECT employee_id, last_name, salary FROM employees WHERE FIND_IN_SET(last_name, p_last_names) > 0; -- 4. 展示更新前后的数据 SELECT '更新前薪资' AS type, * FROM temp_salary_before; SELECT '更新后薪资' AS type, * FROM temp_salary_after; -- 临时表会在会话结束后自动销毁,无需手动清理 END // DELIMITER ;
调用示例:
CALL UpdateEmployeeSalary('Smith,Johnson,Williams');
注意:如果员工姓氏包含逗号,可换用竖线|等其他分隔符,同时将存储过程中的FIND_IN_SET(last_name, p_last_names)替换为FIND_IN_SET(last_name, REPLACE(p_last_names, '|', ',')),调用时传'Smith|O,Neil'这类参数即可。
方案2:使用JSON数组传参(MySQL 8.0及以上版本)
MySQL 8.0及以上支持JSON类型,用JSON数组传参更规范,能避免分隔符冲突问题:
DELIMITER // CREATE PROCEDURE UpdateEmployeeSalary(IN p_last_names JSON) BEGIN -- 1. 创建更新前的临时表 CREATE TEMPORARY TABLE IF NOT EXISTS temp_salary_before ( employee_id INT, last_name VARCHAR(50), salary DECIMAL(10,2) ); INSERT INTO temp_salary_before SELECT e.employee_id, e.last_name, e.salary FROM employees e JOIN JSON_TABLE( p_last_names, '$[*]' COLUMNS(last_name VARCHAR(50) PATH '$') ) AS names ON e.last_name = names.last_name; -- 2. 更新薪资 UPDATE employees e JOIN JSON_TABLE( p_last_names, '$[*]' COLUMNS(last_name VARCHAR(50) PATH '$') ) AS names ON e.last_name = names.last_name SET e.salary = e.salary * 1.02; -- 3. 创建更新后的临时表 CREATE TEMPORARY TABLE IF NOT EXISTS temp_salary_after ( employee_id INT, last_name VARCHAR(50), salary DECIMAL(10,2) ); INSERT INTO temp_salary_after SELECT e.employee_id, e.last_name, e.salary FROM employees e JOIN JSON_TABLE( p_last_names, '$[*]' COLUMNS(last_name VARCHAR(50) PATH '$') ) AS names ON e.last_name = names.last_name; -- 4. 展示数据 SELECT '更新前薪资' AS type, * FROM temp_salary_before; SELECT '更新后薪资' AS type, * FROM temp_salary_after; END // DELIMITER ;
调用示例:
CALL UpdateEmployeeSalary('["Smith","Johnson","O\'Neil"]');
整合已拆分的子存储过程
如果你已经拆分出处理临时表的子存储过程(比如CreateBeforeSalaryTable和CreateAfterSalaryTable),可以将多参数处理逻辑放在主存储过程中,调用子存储过程完成临时表生成:
DELIMITER // CREATE PROCEDURE UpdateEmployeeSalary(IN p_last_names VARCHAR(1000)) BEGIN -- 调用子存储过程生成更新前临时表 CALL CreateBeforeSalaryTable(p_last_names); -- 执行薪资更新 UPDATE employees SET salary = salary * 1.02 WHERE FIND_IN_SET(last_name, p_last_names) > 0; -- 调用子存储过程生成更新后临时表 CALL CreateAfterSalaryTable(p_last_names); -- 展示数据 SELECT '更新前薪资' AS type, * FROM temp_salary_before; SELECT '更新后薪资' AS type, * FROM temp_salary_after; END // DELIMITER ;
需确保子存储过程能接收多姓氏参数并正确生成对应临时表。
内容的提问来源于stack exchange,提问作者Demetris Demetriou
相关产品推荐
相关产品推荐

