Following the previous post, I wondered if there's a more elegant way to call a function. It turns out there is and it's based on CallableStatement
:
int value = jdbcOperations.execute(
new CallableStatementCreator() {
// ...
},
new CallableStatementCallback<Integer>() {
// ...
}
);
The CallableStatementCreator
sets up the statement and the CallableStatementCallback
executes the statement and returns the value up to the execute()
call.
Having a function:
CREATE OR REPLACE FUNCTION HAS_PANEL_FLAG_OK(
P_USER_ID in USERS.USER_ID%TYPE,
P_PANEL_ID in PANELS.PANEL_ID%TYPE,
)
RETURN integer
IS
lv_count NUMBER;
BEGIN
SELECT count(*) into lv_count
FROM USERS
WHERE USERS.PANEL_ID = P_PANEL_ID and USERS.USER_ID = P_USER_ID;
return lv_count;
EXCEPTION
when OTHERS then
return 0;
END;
We can build a query string like:
static final String PANEL_OPERATIONS_OK =
"{ ? = call HAS_PANEL_FLAG_OK(?, ?) }";
The CallableStatementCreator
instance is then:
CallableStatementCreator statementCreator =
new CallableStatementCreator() {
@Override
public CallableStatement createCallableStatement(Connection con) throws SQLException {
CallableStatement cs = con.prepareCall(PANEL_OPERATIONS_OK);
cs.registerOutParameter(1, Types.INTEGER); // The returned result
cs.setString(2, userId);
cs.setString(3, panelId);
return cs;
}
}
This states the first parameter is a result, the second and 3rd parameter are function parameters.
NOTE: Be careful because you can specify indices or keywords for parameter positioning, but you're not allowed to mix the two!
The CallableStatementCallback
is:
CallableStatementCallback<Integer> statementCallback =
new CallableStatementCallback<Integer>() {
@Override
public Integer doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
cs.execute();
int result = cs.getInt(1);
return result; // Propagated to the jdbcTemplate.execute method
}
}
This will execute the statement and will return the result (first parameter of the statement).
The jdbcOperations.execute()
function will return the result from CallableStatementCallback
's doInCallableStatement()
.
The full java code looks like this:
int value = jdbcOperations.execute(
statementCreator,
statementCallback
);
This is much more powerful. You can customise all function's parameters the same as with a classic SQL query.
HTH,
Member discussion: