java - Implementing a Stored Procedure Call with Optional Parameters in Spring 3.0 -
i've been trying find way make stored proc calls spring 3.0 oracle 11.2 following items in mind:
- many of calls made stored procedures have plethora of optional parameters (parameters have default values).
- there stored procedures can have mix of:
in,out, and/orin out. - i not need handle
out's.
i able call stored proc needed parameters (required and/or optional). in other word, do not wish pass value (not null) optional parameters choosing (it seems when null being passed programmatically [not in pl/sql though] parameter mapper, default values don't used). have attempted implement these invocations many possible ways nothing has worked:
create or replace procedure update_stored_proc ( h1 in boolean default false, h2 in number, h3 in varchar2 default 'h3', h4 in varchar2 default 'h4', h5 in varchar2 default 'h5', h6 in out number ); for update_stored_proc(), there 2 required parameters (h2 , h6), , 4 optional ones. ultimate goal call update_stored_proc() passing h1, h2 , h6. when invoking stored proc via simplejdbccall values set, exception:
simplejdbccall simplejdbccall = new simplejdbccall(updatingdatasource) .withprocedurename("update_stored_proc") .withoutprocedurecolumnmetadataaccess(); simplejdbccall.declareparameters(new sqlparameter("h1", oracletypes.boolean)) .declareparameters(new sqlparameter("h2", oracletypes.number)) .declareparameters(new sqlparameter("h3", oracletypes.varchar)) .declareparameters(new sqlparameter("h4", oracletypes.varchar)) .declareparameters(new sqlparameter("h5", oracletypes.varchar)) .declareparameters(new sqlinoutparameter("h6", oracletypes.number)); mapsqlparametersource in = new mapsqlparametersource() .addvalue("h1", false, oracletypes.boolean) .addvalue("h2", 123, oracletypes.number) .addvalue("h3", "h3", oracletypes.varchar) .addvalue("h4", "h4", oracletypes.varchar) .addvalue("h5", "h5", oracletypes.varchar) .addvalue("h6", "h6", oracletypes.number); simplejdbccall.compile(); simplejdbccall.execute(in); the exception indicates column type somehow invalid:
org.springframework.jdbc.uncategorizedsqlexception: callablestatementcallback; uncategorized sqlexception sql [{call update_stored_proc(?, ?, ?, ?, ?, ?)}]; sql state [99999]; error code [17004]; invalid column type; nested exception java.sql.sqlexception: invalid column type i have replaced oracletypes types , taken out withoutprocedurecolumnmetadataaccess() error persists.
this question turned out require several solutions work. first , foremost, oracle's implementation of sql standards not contain boolean type, though propriety pl/sql script language support (more reason dba's not use boolean type in stored procedures). solution came use anonymous block, declare local variable, , assign boolean parameter:
declare h1_false boolean := false; h6_ number; begin update_stored_proc( h1 => h1_false, h2 => :h2, h6 => h6_ ); end; note not care value of h1 (and matter, out parameter/h6) parameter particular functionality, imagine having simple if else statement, 1 can assign binded parameter h1, i.e.
declare h1_false boolean; h6_ number; begin if :h1 h1_false = true; else h1_false = false; end if; update_stored_proc( h1 => h1_false, h2 => :h2, h6 => h6_ ); end; the second issue way spring handles optional parameters. if 1 declare optional parameters, spring's simplejdbccall -- , storedprocedure matter -- expects values parameters. therefore, 1 must take care of these values when become available. otherwise, when optional parameter not have value, must pass null will not trigger default value of pl/sql's parameter used. means query string (in case anonymous pl/sql block) must generated dynamically. so, anonymous block becomes:
declare h1_false boolean := false; h6_ number; begin update_stored_proc( h1 => h1_false, h2 => :h2, h6 => h6_ i switched storedprocedure solution rather simplejdbccall, turned out more simpler. albeit must add had extend storedprocedure create common class stored procedure classes , use extended class customized stored procedure classes. in storedprocedure class, declare required parameters (make sure not compile() query @ point):
declareparameter(new sqlparameter("h2", oracletypes.number)); note: if not need out parameter, in case, not include in declaration. otherwise, assign binding variable, i.e. h6 => :h6 in anonymous block , declare in storedprocedure, i.e. declareparameter(new sqloutparameter("h6", oracletypes.number)); , make sure :h6 value out when execute() returns map<string, object>. if out value of boolean type, not know how retrieve value.
the remaining optional parameters should dynamically constructed in storedprocedure. i.e.:
if (someobj.geth3() != null) { declareparameter(new sqlparameter("h3", oracletypes.varchar)); parammap.put("h3", someobj.geth3()); anonymousplsqlblockquerystring += " , h3 => :h3"; } where parammap represents map going passed storedprocedure#execute(parammap). same h4 , h5, , @ end, have make sure close anonymous block query string, i.e.:
anonymousplsqlblockquerystring += " ); end;"; setsql(anonymousplsqlblockquerystring); setsqlreadyforuse(true); compile();
Comments
Post a Comment