MySQL存储过程在Spring Boot集成测试中执行报错
解决Spring Boot集成测试执行MySQL存储过程脚本时
blockCommentEndDelimiter未知错误 我写了个truncate_tables的MySQL存储过程,用来在Spring Boot集成测试前清空当前Schema下的所有表,在MySQL Workbench里运行完全正常,但用@Test搭配@Sql注解执行脚本时,却抛出org.springframework.jdbc.datasource.init.ScriptStatementFailedException,根源是java.sql.SQLException: Unknown system variable 'blockCommentEndDelimiter'。环境为Spring Framework 5、Testcontainers MySQL 5.7镜像。
问题根因
Spring底层依赖的ScriptUtils工具在解析SQL脚本时,默认的注释处理、语句分隔逻辑和MySQL Workbench不一致,会误把存储过程内的部分语法识别成系统变量,从而触发报错。
解决办法
1. 调整SQL脚本的分隔符
在存储过程脚本开头显式设置MySQL分隔符为//,避免Spring把存储过程内部的;当成语句结束符,脚本示例:
DELIMITER // DROP PROCEDURE IF EXISTS truncate_tables// CREATE PROCEDURE truncate_tables() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE tablename VARCHAR(255); DECLARE cur CURSOR FOR SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE(); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO tablename; IF done THEN LEAVE read_loop; END IF; SET @stmt = CONCAT('TRUNCATE TABLE ', tablename); PREPARE stmt FROM @stmt; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP; CLOSE cur; END // DELIMITER ;
2. 配置@Sql的解析规则
在测试类的@Sql注解里指定分隔符和注释前缀,让Spring正确解析存储过程:
@Sql(scripts = "/truncate_tables.sql", config = @SqlConfig(separator = "//", commentPrefix = "--")) @Test void yourIntegrationTest() { // 测试逻辑 }
把分隔符设为//,注释前缀设为--,就能避免Spring把块注释误判成系统变量。
3. 绕开脚本解析:直接用JdbcTemplate调用
要是上面的方法仍不生效,可以直接在测试类里注入JdbcTemplate,手动调用存储过程:
@Autowired private JdbcTemplate jdbcTemplate; @BeforeEach void truncateTables() { jdbcTemplate.execute("CALL truncate_tables()"); }
这种方式跳过Spring的脚本解析器,直接通过JDBC调用存储过程,不会出现解析错误。
内容的提问来源于stack exchange,提问作者ishan
相关产品推荐
相关产品推荐

