Question

I am trying to call a SQLServer stored Scalar function through Apache Common DbUtils. I tried something like this:

run.query("SELECT [MyDB].[dbo].[test] ('testParam')", new ScalarHandler());

But, I get this exception:

com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: Unable to identify the table SELECT [MyDB].[dbo].[test] ('testParam') for the metadata.

While, running the same query in the SQLServer returns a valid Scalar value.

I am wondering how can I call a Scalar function using Apache DbUtils.

UPDATE: For Table-valued functions it works if I ues "SELECT * FROM..."

Was it helpful?

Solution

It looks that there is a bug in Apache Common DbUtils (v. 1.5) AbstractQueryRunner (base class of QueryBuilder) code. It has parameter pmdKnownBroken, which desribed as follows:

if pmdKnownBroken is set to true, we won't even try it; if false, we'll try it, and if it breaks, we'll remember not to use it again.

But does not work as described, becausefillStatementmethod does not catch an exception when calling java.sql.getParameterMetaData.

So you should set pmdKnownBroken to true.

OTHER TIPS

I am not sure if it is possible to run a SQL Server scalar function with DBUtils, try by this way

Object[] params = {"inputparam"};
ScalarHandler<T> scalar = new ScalarHandler<T>();
run.query("{CALL DB.dbo.test(?)}", scalar, params);

If you don't find a solution with DBUtils yo can use a CallableStatement

String url = "jdbc:sqlserver://....";
SQLServerDataSource sqls = new SQLServerDataSource();
sqls.setURL(url);
sqls.getConnection();

CallableStatement callStatement = sqls.getConnection().prepareCall("{? = CALL DB.dbo.f_promedio(?,?)}");
callStatement.setDouble(2, 1.8);
callStatement.setDouble(3, 6.8);
callStatement.registerOutParameter(1, java.sql.Types.DECIMAL);
callStatement.execute();

double d = callStatement.getDouble(1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top