This question turned out to require several solutions to get to work. First and foremost, Oracle's implementation of SQL standards does not contain BOOLEAN
type, even though its propriety PL/SQL script language does support it (more reason for the DBA's not to use BOOLEAN
type in their stored procedures). The solution I came up with was to use an anonymous block, declare a local variable, and assign it to the BOOLEAN
parameter:
DECLARE
h1_false BOOLEAN := false;
h6_ NUMBER;
BEGIN
update_stored_proc(
h1 => h1_false,
h2 => :h2,
h6 => h6_
);
END;
Note that I do not care about the value of h1
(and for that matter, the OUT
parameter/h6
) parameter for my particular functionality, but I could imagine by having a simple IF THEN ELSE
statement, one can assign a binded parameter to h1
, i.e.
DECLARE
h1_false BOOLEAN;
h6_ NUMBER;
BEGIN
IF :h1 THEN
h1_false = true;
ELSE
h1_false = false;
END IF;
update_stored_proc(
h1 => h1_false,
h2 => :h2,
h6 => h6_
);
END;
The second issue is the way Spring
handles the optional parameters. If one to declare the optional parameters, then Spring
's SimpleJdbcCall
-- and StoredProcedure
for that matter -- expects values for those parameters. Therefore, one must take care of these values when they become available. Otherwise, when the optional parameter does not have a value, you must pass NULL
which will not trigger the DEFAULT value of the PL/SQL's parameter to be used. This means that your query string (in this case an anonymous PL/SQL block) must be generated dynamically. So, the anonymous block becomes:
DECLARE
h1_false BOOLEAN := false;
h6_ NUMBER;
BEGIN
update_stored_proc(
h1 => h1_false,
h2 => :h2,
h6 => h6_
I switched to StoredProcedure
solution rather than SimpleJdbcCall
, as it turned out to be more simpler. Albeit I must add that I had to extend StoredProcedure
to create a common class for my stored procedure classes and use that extended class for my customized stored procedure classes. In your StoredProcedure
class, you only declare the required parameters (make sure not to compile()
the query at this point):
declareParameter(new SqlParameter("h2", OracleTypes.NUMBER));
Note: If you do not need the OUT
parameter, like in my case, do not include it in your declaration. Otherwise, assign a binding variable, i.e. h6 => :h6
in the anonymous block and declare it in your StoredProcedure
, i.e. declareParameter(new SqlOutParameter("h6", OracleTypes.NUMBER));
and make sure to get :h6
value out when execute()
returns a Map<String, Object>
. If your OUT
value is of BOOLEAN
type, then I do not know how to retrieve the value.
The remaining optional parameters should be dynamically constructed in your StoredProcedure
. i.e.:
if (someObj.getH3() != null) {
declareParameter(new SqlParameter("h3", OracleTypes.VARCHAR));
paramMap.put("h3", someObj.getH3());
anonymousPLSQLBlockQueryString += " , h3 => :h3";
}
where paramMap
represents a Map
that is going to be passed to StoredProcedure#execute(paramMap)
. You do the same with h4
and h5
, and at the end, you have to make sure to properly close the anonymous block query string, i.e.:
anonymousPLSQLBlockQueryString += " ); END;";
setSql(anonymousPLSQLBlockQueryString);
setSqlReadyForUse(true);
compile();