【发布时间】:2017-09-19 07:13:33
【问题描述】:
我正在尝试在方法中使用 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
}
假设存储过程名称为ABC,参数为@a。
现在 DatabaseMetaData 返回列名 @a 但设置 st.setInt("@a",0) 返回以下错误:
com.microsoft.sqlserver.jdbc.SQLServerException:未为存储过程 ABC 定义参数 @a。
相反,我尝试了这个:st.setInt("a",0),它完美地执行了。
现在的问题是我必须动态设置参数,因为我有太多的存储过程和太多的参数,但是 jdbc 给出了错误。
编辑 1:
正如在一个答案中指出的那样,我的问题与:Named parameters in JDBC 重复,我想解释一下,这里的问题不是命名参数或位置参数,而是关于 JDBC 不处理 SQL 服务器参数本身正确或我在调用它时犯了一些错误。
【问题讨论】:
-
不确定我是否理解正确,但为什么不能(你不能动态剥离
@? -
@ScaryWombat 我需要一些可以同时用于 mysql 和 sql server 以及其他一些的东西,而无需进行特定更改,因为我希望 JDBC 能够处理它。
-
@Bejasc
CallableStatement是该规则的例外:它确实支持命名参数。 -
对我来说听起来像是一个错误,您可能想在 github.com/Microsoft/mssql-jdbc 上报告它或者元数据应该报告没有
@的名称,或者setXXX应该用@接受它(并且没有向后兼容性)。
标签: java sql-server stored-procedures jdbc mssql-jdbc