记录:jdbc调用sqlserver存储过程

发布时间 2023-08-08 15:40:13作者: 鹿鹿的布丁
  • 1、现场为内网环境,不利于测试
  • 2、调用sql server存储过程,报错:为过程或函数 ** 指定了过多的参数

一、制作本地sql server环境

1、docker安装sql server

#获取镜像
docker pull mcr.microsoft.com/azure-sql-edge
#启动 账号: sa 密码: Password@
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password@' -p 1433:1433  --name sqlserver -d 镜像名称

image.png

2、建表

建一张名为: t_test_proc

略。。。

3、创建存储过程

create proc proc_query_with_arg 
@v1 varchar(40),
@v2 varchar(40),
@v3 varchar(40)
as 
select * from t_test_proc where create_time >= @v1 and create_time <= @v2 AND test_status = @v3

#直接调用
exec proc_query_with_arg @v1 = '20230101', @v2 = '20231230' , @v3= '2';

二、使用jdbc调用

1、修改数据库连接配置

# 数据库配置需要根据安装的sqlserver修改
# 当前设置是用上面的 docker 安装后的配置
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433;DatabaseName=master
username: sa
password: Password@

2、测试问题代码

经过测试,查询当前存储过程的时候只需要设置入参即可
是否需要设置出参类型影响因素(猜测):

  • 数据库类型 sql server 、oracle、 mysql
  • 存储过程写法,没有用@设置返回值
public List<TestEntity> queryTestProc(String startDate, String endDate) {
    log.info("查询入参为:{},{}",startDate,endDate);
    List<TestEntity> testEntityList = new ArrayList<>();
    try (Connection conn = dataSource.getConnection()){
        ResultSetMapper<TestEntityQuery> resultSetMapper = new ResultSetMapper<>();
        log.info("获取数据库连接成功");
        //问题代码,只需要设置三个入参即可
        //CallableStatement cstmt = conn.prepareCall("{ call proc_query_with_arg(?,?,?,?) }");
        CallableStatement cstmt = conn.prepareCall("{ call proc_query_with_arg(?,?,?) }");
        cstmt.setString(1, startDate);
        cstmt.setString(2, endDate);
        cstmt.setString(3, "2");
        //问题代码,多了设置返回值类型,会报错
        //cstmt.registerOutParameter(4, Types.ARRAY);
        ResultSet resultSet = cstmt.executeQuery();
        log.info("执行存储过程成功");
        List<TestEntityQuery> pojoList = resultSetMapper.mapRersultSetToObject(resultSet, TestEntityQuery.class);
        if (CollectionUtils.isNotEmpty(pojoList) && pojoList != null) {
            for (TestEntityQuery pojo : pojoList) {
                log.info("执行存储过程的结果为:{}", pojo);
                //....略
            }
        } else {
            log.info("ResultSet is empty. Please check if database table is empty");
        }

    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
    return testEntityList;
}