首页 > 解决方案 > JDBC 可调用语句在本地执行,但在 Jenkins 中运行时“没有为参数号 2 设置值”

问题描述

我在 Java Maven 项目中使用 jdbc.SQLServerDriver 将测试记录插入到测试报告数据库中。当我通过 Intellij 或通过在 Powershell 中运行“mvn clean compile”、“mvn test”在本地运行测试时,记录已成功插入数据库。但是,当我通过 Jenkins(声明性管道)运行时,我收到以下错误消息:com.microsoft.sqlserver.jdbc.SQLServerException: The value is not set for the parameter number 2.

我查看了 CallableStatement 周围的几个资源和几个关于错误消息的 StackOverflow 帖子,但我不明白为什么在本地运行时会设置参数,但在 Jenkins 中却没有。

这是我的詹金斯文件:

pipeline {
    agent any
    stages {
        stage('Compile') {
            steps {
                withMaven(maven: 'LocalMaven'){
                    bat 'mvn clean compile'
                }
            }
        }
        stage('Test') {
            steps {
                withMaven(maven: 'LocalMaven'){
                    bat 'mvn test'
                }
            }
        }
    }
}

这是我执行存储过程的代码:

public static void ExecuteStoredProc(String procedureName, Hashtable parameters, Connection connection)
{

    try {
        String paraAppender;
        StringBuilder builder = new StringBuilder();
        // Build the paramters list to be passed in the stored proc
        for (int i = 0; i < parameters.size(); i++) {
            builder.append("?,");
        }

        paraAppender = builder.toString();
        paraAppender = paraAppender.substring(0,
                paraAppender.length() - 1);

        CallableStatement stmt = connection.prepareCall("{Call "
                + procedureName + "(" + paraAppender + ")}");

        // Creates Enumeration for getting the keys for the parameters
        Enumeration params = parameters.keys();

        // Iterate in all the Elements till there is no keys
        while (params.hasMoreElements()) {
            // Get the Key from the parameters
            String paramsName = (String) params.nextElement();
            // Set Paramters name and Value
            stmt.setString(paramsName, parameters.get(paramsName)
                    .toString());
        }

        // Execute Query
        stmt.execute();
    } catch (Exception e) {
        System.out.println(procedureName);
        System.out.println(parameters.keySet());
        System.out.println(e.getMessage());

    }
}

}

这是我在哈希表中传递的值:

public static void CreateRun(Connection connection)
{

    //Params
    Hashtable table = new Hashtable();
    table.put("Machine", "Machine");
    table.put("ClientOS", "CLientOS");
    table.put("Environment", "Environment");
    table.put("Browser", "Browser");
    table.put("BrowserVersion", "BrowserVersion");
    table.put("RunBuild", "RunBuild");
    table.put("DevMachine", "1");
    table.put("ExpectedCases", "1");

    DatabaseUtil.ExecuteStoredProc("sp_CreateRun",table, connection );

}

这是存储的过程:

... PROC [dbo].[sp_CreateRun]
@Machine varchar(45),
@ClientOS     varchar(45),
@Environment varchar(45),
@Browser varchar(45),
@BrowserVersion varchar(45),
@RunBuild varchar(45),
@DevMachine bit,
@ExpectedCases int

AS
BEGIN
    INSERT into Run (Start_Time, End_Time, Machine, Client_OS, Environment, Browser, Browser_Version, Run_Build, Dev_Machine, Expected_Cases)
     values (GETDATE(),GetDate(),@Machine,@ClientOS,@Environment,@Browser, @BrowserVersion,@RunBuild,@DevMachine,@ExpectedCases)
END

提前感谢您查看。

标签: javajenkinsjdbccallable-statement

解决方案


谢谢大家的有用评论。我从来没有弄清楚如何使用 CallableStatement 进行这项工作,但我确实使用 Spring SimpleJdbcCall 在本地和 Jenkins 上工作。我真的很喜欢现在的代码有多干净。

public static void ExecuteStoredProc(String procedureName, Map<String, String> parameters)
{
    JdbcTemplate template = new JdbcTemplate(SpringJDBCConfig.sqlDataSource());

    MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();

    for (String key : parameters.keySet()) {
        sqlParameterSource.addValue(key, parameters.get(key));
    }

    SimpleJdbcCall call = new SimpleJdbcCall(template)
            .withCatalogName("matrix")
            .withSchemaName("dbo")
            .withProcedureName(procedureName);

   call.execute(sqlParameterSource);
}

推荐阅读