[英]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.