简体   繁体   English

未为存储过程定义参数@ x…使用MS_SQL JDBC

[英]Parameter @x was not defined for stored procedure… with MS_SQL JDBC

I am trying to execute a stored procedure using SQL Server JDBC in a method: 我正在尝试在一种方法中使用SQL Server JDBC执行存储过程:

//Connection connection, String sp_name, Map<String, Object>params input to the method
DatabaseMetaData dbMetaData = connection.getMetaData();
HashMap<String, Integer> paramInfo = new HashMap<String, Integer>();
if (dbMetaData != null)
{
        ResultSet rs = dbMetaData.getProcedureColumns (null, null, sp_name.toUpperCase(), "%");
        while (rs.next())
            paramInfo.put(rs.getString(4), rs.getInt(6));
        rs.close();
}
String call = "{ call " + sp_name + " ( ";
for (int i = 0; i < paramInfo.size(); i ++)
    call += "?,";
if (paramInfo.size() > 0)
    call = call.substring(0, call.length() - 1);
call += " ) }";
CallableStatement st = connection.prepareCall (call);
for (String paramName: paramInfo.keySet()){
    int paramType = paramInfo.get(paramName);
    System.out.println("paramName="+paramName);
    System.out.println("paramTYpe="+paramType);
    Object paramVal = params.get(paramName);
    st.setInt(paramName, Integer.parseInt(((String)paramVal))); //All stored proc parameters are of type int
}

Let say the stored procedure name is ABC and parameter is @a . 假设存储过程的名称为ABC ,参数为@a Now DatabaseMetaData returns column name @a but setting st.setInt("@a",0) returns following error: 现在DatabaseMetaData返回列名@a但是设置st.setInt("@a",0)返回以下错误:

com.microsoft.sqlserver.jdbc.SQLServerException: Parameter @a was not defined for stored procedure ABC. com.microsoft.sqlserver.jdbc.SQLServerException:未为存储过程ABC定义参数@a。

Instead, I tried this: st.setInt("a",0) and it executed perfectly. 相反,我尝试了一下: st.setInt("a",0) ,它执行得很好。

Now the problem is I have to set the parameters dynamically as I have too many stored procedures and too many parameters but jdbc is giving error. 现在的问题是我必须动态设置参数,因为我有太多的存储过程和太多的参数,但是jdbc给出了错误。

Edit 1: 编辑1:

As pointed out in one answer that my question is a duplicate of: Named parameters in JDBC , I would like to explain that the issue here is not named parameters or positional ones, rather it is about JDBC not handling the SQL server parameters itself properly or my making some error while invoking it. 正如一个答案中指出的那样,我的问题是以下内容的重复: JDBC中的命名参数 ,我想解释一下这里的问题不是命名参数或位置参数,而是关于JDBC无法正确处理SQL Server参数本身或我在调用它时出错了。

Update 2017-10-07: The merge request to fix this issue has been accepted, so this should no longer be a problem with versions 6.3.4 and later. 更新2017年10月7日: 修复了此问题合并请求已被接受,因此版本6.3.4和更高版本不再是问题。


Yes, it is an unfortunate inconsistency that for mssql-jdbc the parameter names returned by DatabaseMetaData#getProcedureColumns do not match the names accepted by CallableStatement#setInt et. 是的,对于mssql-jdbc,不幸的不一致之处是DatabaseMetaData#getProcedureColumns返回的参数名称与CallableStatement#setInt 接受的名称不匹配 al. . If you consider it to be a bug then you should create an issue on GitHub and perhaps it will be fixed in a future release. 如果您认为它是一个错误,则应在GitHub上创建一个问题 ,也许它将在将来的版本中得到修复。

In the meantime, however, you'll just have to work around it. 但是,与此同时,您只需要解决它。 So, instead of code like this ... 因此,而不是像这样的代码...

ResultSet rs = connection.getMetaData().getProcedureColumns(null, "dbo", "MenuPlanner", null);
while (rs.next()) {
    if (rs.getShort("COLUMN_TYPE") == DatabaseMetaData.procedureColumnIn) {
        String inParamName = rs.getString("COLUMN_NAME");
        System.out.println(inParamName);
    }
}

... which produces ... ...产生...

@person
@food

... you'll need to use code like this ... ...您将需要使用这样的代码...

boolean isMssqlJdbc = connection.getClass().getName().equals(
        "com.microsoft.sqlserver.jdbc.SQLServerConnection");
ResultSet rs = connection.getMetaData().getProcedureColumns(null, "dbo", "MenuPlanner", null);
while (rs.next()) {
    if (rs.getShort("COLUMN_TYPE") == DatabaseMetaData.procedureColumnIn) {
        String inParamName = rs.getString("COLUMN_NAME");
        if (isMssqlJdbc && inParamName.startsWith("@")) {
            inParamName = inParamName.substring(1, inParamName.length());
        }
        System.out.println(inParamName);
    }
}

... which produces ... ...产生...

person
food

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用JDBC / Spring调用Oracle存储过程,其中一些参数类型是用户定义的? - How can I call an Oracle stored procedure with JDBC/Spring where some of the parameter types are user defined? JDBC-如何获取存储过程的参数名称 - JDBC - How to get parameter name of a stored procedure 使用 JDBC 将用户定义的表类型传递给 SQL Server 存储过程 - Passing a user-defined table type to a SQL Server stored procedure using JDBC 如何使用Spring JDBC存储过程从Java将用户定义的数据类型变量的值传递给MS SQL - How to pass the values of user defined datatype variable to MS SQL from java using spring jdbc store procedure JDBC MySQL存储过程抛出异常“参数编号2不是OUT参数”吗? - JDBC MySQL stored procedure throw exception “ Parameter number 2 is not an OUT parameter”? 使用JDBC以自定义类型输入参数调用PL / SQL存储过程,所有字段均为空 - Using JDBC to call a PL/SQL stored procedure with custom type input parameter, all fields are null 使用JDBC以用户定义的记录作为其IN参数调用PL / SQL过程 - Calling PL/SQL procedure with user defined record as its IN parameter using JDBC 错误:未为存储过程定义参数输出 - Error: Parameter out was not defined for stored procedure JDBC存储过程调用 - JDBC stored procedure call 在jdbc中调用存储过程 - Calling stored procedure in jdbc
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM