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

如何将JDBI @SqlCall调用的存储过程中print语句输出到Java应用日志?

解决Micronaut+JDBI捕获SQL Server存储过程PRINT输出的问题

核心原理

SQL Server的PRINT语句输出会被JDBC驱动封装为SQLWarning返回(而非结果集),只要在JDBI执行流程中加入逻辑提取这些警告,就能将其记录到应用日志里。

实现步骤

1. 编写JDBI语句拦截器

利用JDBI的StatementInterceptor接口,在存储过程执行后提取并记录警告:

import org.jdbi.v3.core.statement.StatementContext;
import org.jdbi.v3.core.statement.StatementInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;

public class SqlServerPrintLogger implements StatementInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(SqlServerPrintLogger.class);

    @Override
    public void afterExecution(Statement stmt, StatementContext ctx) throws SQLException {
        SQLWarning warning = stmt.getWarnings();
        // 遍历所有警告,SQL Server的PRINT输出对应SQL状态码01000
        while (warning != null) {
            if ("01000".equals(warning.getSQLState())) {
                LOG.debug("存储过程PRINT输出: {}", warning.getMessage());
            }
            warning = warning.getNextWarning();
        }
        // 清除警告,避免后续语句重复处理
        stmt.clearWarnings();
    }
}

2. 在Micronaut中注册拦截器

通过配置工厂类,将自定义拦截器绑定到JDBI实例:

import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import org.jdbi.v3.core.Jdbi;
import javax.sql.DataSource;

@Factory
public class JdbiConfiguration {

    @Bean
    public Jdbi jdbi(DataSource dataSource) {
        Jdbi jdbi = Jdbi.create(dataSource);
        // 注册PRINT日志拦截器
        jdbi.registerStatementInterceptor(new SqlServerPrintLogger());
        return jdbi;
    }
}

3. 正常调用存储过程

使用@SqlCall注解调用存储过程时,拦截器会自动捕获PRINT输出并记录:

import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.statement.SqlCall;

public interface LegacyProcDao {
    @SqlCall("{call Legacy_Proc_Name(:inputParam)}")
    void executeLegacyProc(@Bind("inputParam") String input);
}

注意事项

  • 确保使用的SQL Server JDBC驱动(com.microsoft.sqlserver:mssql-jdbc)为稳定新版本,旧版本可能存在PRINT输出处理差异。
  • 调整日志级别为DEBUG(或对应级别)才能看到输出,若需要更醒目可改为LOG.info()。
  • 该逻辑不影响存储过程结果集的正常处理,仅额外捕获PRINT输出。

内容的提问来源于stack exchange,提问作者maborg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:18:12