You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:42:19