Invoking procedure defaults without binding values to parameters in Jdbc

陌路散爱 提交于 2019-12-11 07:55:55

问题


I am trying to call a PL/SQL procedure which has defaults defined for some of its parameters. I am doing this using CallableStatement in JDBC.

This procedure has a large number of parameters with defaults defined. I do not want to explicitly set the defaults in the Java code. Doing this would make maintaining the code harder. If the PL/SQL code changes , would have to make the same changes in the Java code too.

Is it possible to accomplish this in JDBC ? For instance just bind values to the parameter you are interested in and ignore the rest.

I tried this on the following sample procedure :

  -- PURPOSE: Takes a parameter which has defaults set. Returns the value of the same parameter
  -- Example of: FUNCTION that takes a parameter with DEFAULT values  
  FUNCTION handle_defaults(empId IN NUMBER DEFAULT 20 , empCity IN VARCHAR2) RETURN NUMBER IS
  BEGIN
    RETURN empId;
  EXCEPTION
    WHEN others THEN
    dbms_output.put_line('Error!');
  END handle_defaults;

Here is the relevant portions of the code (NOTE: Have stripped off the try catch block , cleaning up of database resources etc for sake of readability)

         // Create a database connection
         conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);

         // Create a query string
         String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( ? , ? ) }";

         // Create a Callable Statements
         callStmt = conn.prepareCall(queryStr);

         // Bind values to the IN parameter
         callStmt.setString(3, "Mumbai");

         // Register OUT parameter 
         callStmt.registerOutParameter(1, java.sql.Types.NUMERIC);

         // Execute the Callable Statement
         callStmt.execute();

         // Retrieve the value of the OUT parameter
         parameterValue = callStmt.getInt(1);

         System.out.println("Value returned : " + parameterValue);

I get the following error:

Exception occured in the database
java.sql.SQLException: Missing IN or OUT parameter at index:: 2
Database error code: 17041

As a desperate attempt I also tried to pass Nulls for those parameters. Just included the following line:

callStmt.setNull(2, java.sql.Types.NUMERIC);

I get the following result:

Value returned : 0

That makes sense bcoz setNull supplies SQL Null to the parameter.

I am using Oracle 11g and Oracle 12c Jdbc Driver Version 12.1.0.2.


回答1:


I don't think there's a simple answer to this question, and that's not because of JDBC, but because of Oracle.

Put simply, the only way I know of calling a procedure and using the default value for a parameter is to not specify the parameter when you call the procedure.

If you are writing

     String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( ? , ? ) }";

you are always specifying both parameters, so you can never use the default value for one of them. If you only want to specify one of them and use the default for the other, write:

     String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( empCity => ? ) }";

In this case you need to specify the parameter name in the call, as the first parameter is the optional one. If the second parameter was optional instead, the parameter name can be dropped.

Unfortunately, this becomes quite complicated for your real procedure with lots of parameters. What I would do would be to:

  • Use a StringBuilder to build up the procedure call string.
  • Run through the parameters, adding paramName => ? parts to it for each parameter you have a value for. Ensure the parts are separated by commas.
  • Prepare a CallableStatement using the output of the StringBuilder.
  • Run through the parameters again and call various setString/setInt/setDate/etc. methods on the CallableStatement for each parameter you have a value for.


来源:https://stackoverflow.com/questions/27433850/invoking-procedure-defaults-without-binding-values-to-parameters-in-jdbc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!