SQLException when executing a callablestatement - java

I am trying to call a Procedure from a package from my java application but receive an error. The code is set up like so...
------Java-----
Connection = conn;
String call_code="{? = call MY_PROCEDURE.Process_vale(?,?,?)}";
CallableStatement Process_cs=conn.prepareCall(call_code);
String bValue= "12345";
Process_cs.setString(1, bValue);
Process_cs.registerOutParameter(2, Types.INTEGER);
Process_cs.registerOutParameter(3, Types.VARCHAR);
Process_cs.execute();
The Procedure is setup like:
PROCEDURE Process_value (bValue VARCHAR2, PN_CD OUT NUMBER, PN_MSG OUT VARCHAR2).....
The Error I see is:
java.sql.SQLException: Missing IN or OUT parameter at index:: 4
I am curious as to why it mentions an index of 4, when the Procedure only has 3 parameters, I believe I am missing a critical fact here.

You have done some serious mistakes here. First Since you are calling a procedure you wont get any return value, only functions can have return values. So you have to call the procedure as follows.
String call_code="{call MY_PROCEDURE.Process_vale(?,?,?)}";
You could be successfully execute this if your procedure first parameter is IN type and other two parameters are OUT type.

Related

method Name execute This statement does not declare an OUT parameter. Use { ?= call ... } to declare one

I had migrated database from Oracle to AWS Aurora PostgreSQL. I saw that all the packages are migrated as Function in PostgreSQL. I used AWS SCT for the Oracle schema conversion to postgreSQL. Java is the application middleware.
for example,
A package and associated stored proc in Oracle pk_audit.sp_get_audit converted to postgreSQL as pk_audit$sp_get_audit with a $ symbol.
When I run the web application, I'm getting an error like method Name execute This statement does not declare an OUT parameter. Use { ?= call ... } to declare one .
I don't have access to the application, but App team provided weblogic log. It says,
Method Name execute org.postgresql.util.PSQLException:
This statement does not declare an OUT parameter.Use { ?= call ... } to declare one.
org.postgresql.jdbc.PgCallableStatement.registerOutParameter(PgCallableStatement.java:205) weblogic.jdbc.wrapper.CallableStatement_org_postgresql_jdbc_PgCallableStatement.registerOutParameter(Unknown Source
package name specified in the Java code is pk_audit.sp_get_audit
Renamed the Postgres function pk_audit$sp_get_audit to pk_audit.sp_get_audit still facing the issue.
Is there anything I need to do in PostgreSQL DB ?
I need advise and help,Thanks.
As documented in CallableStatement, the JDBC syntax for calling stored procedures is one of these
{call ProcedureName(?, ...)}
{? = call FunctionName(?, ...)}
Any of the parameters can be OUT parameters. The return value is of course a type of OUT parameter.
So, if you had a stored procedure with 2 parameters and the second parameter was an OUT parameter, you would code it as:
String sql = "{call MyProcedure(?, ?)}";
try (CallableStatement stmt = conn.prepareCall(sql)) {
stmt.setInt(1, p1);
stmt.registerOutParameter(2, Types.VARCHAR);
...
}
If that same procedure is converted into a function, you would code it as:
String sql = "{? = call MyFunction(?)}";
try (CallableStatement stmt = conn.prepareCall(sql)) {
stmt.registerOutParameter(1, Types.VARCHAR);
stmt.setInt(2, p1);
...
}
If you cannot change the Java code making the call, you need to convert your functions back to procedures.

What is 'call' meaning in JDBC callable statement?

I have faced this question in interview. What is call in JDBC callable statement. I know it is not key word.
For example we have following code
String SQL = "{call getEmpName (?, ?)}";
cstmt = conn.prepareCall (SQL);
what is call in the first statement represents?
call is used to execute a database stored procedure. Then, it's followed by the name of the stored procedure and parameters. In fact, this is how the SQL statement generally looks:
"{ ? = call getEmpName (?, ?)}"
Where the first parameter belongs to the output result from the stored procedure (if defined). If the stored procedure doesn't return any data, then this parameter can be omitted.

java.sql.SQLException: Parameter number 2 is not an OUT parameter

I am getting an Error while running this:
1. cs = getCon1().prepareCall("{CALL SaveLabourWageDetails(?,?)}");
2. cs.setString(1, user.getUserId());
3. cs.registerOutParameter(2, java.sql.Types.INTEGER); //<--- ERROR at this line
4. cs.execute();
5. String lastIsertId=cs.getString(2);
The Stored Procedure is :
CREATE
PROCEDURE `cheque_alert`.`SaveLabourDetailsHead`(IN wage_entered_by VARCHAR(10),OUT LastInsertId INT)
BEGIN
INSERT INTO `cheque_alert`.`labour_wage_head`
(
`wage_entered_by`,
`entered_date_time`)
VALUES (wage_entered_by,
NOW());
SELECT LAST_INSERT_ID() INTO LastInsertId;
END$$
DELIMITER ;
Please point out the problem in this code..
You are calling wrong procedure. You have procedure SaveLabourDetailsHead and you are calling
1. cs = getCon1().prepareCall("{CALL SaveLabourWageDetails(?,?)}");
↑
Change to,
1. cs = getCon1().prepareCall("{CALL SaveLabourDetailsHead(?)}");
Set String parameter wage_entered_by.
Your out parameter is of type String, but it should be int. Try this out.
int lastIsertId=cs.getInt(2);
I had the same problem but the output exception is misleading as the root cause was the procedure name.
I typed incorrect procedure which did not exist in database.
Instead of providing a SQL exception something like "routine does not exist", it gave:
java.sql.SQLException: Parameter number 2 is not an OUT parameter.
Just had the same problem.
It was a permission issue in my case. The MySQL user my application uses lacked the EXECUTE permission on the schema I'm working on.
GRANT EXECUTE ON <your_schema>.* TO '<your_user>'#'localhost';
FLUSH PRIVILEGES;

error calling stored procedure from java through callable statement

I am writing a simple java program that calls a oracle stored procedure, but it doesn't work with callable statement.
When I call that stored procedure on SQLDeveloper,
EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'XXXXX', TABNAME=>'XXXXX',
PARTNAME=>'XXXXXYYYYMM', ESTIMATE_PERCENT=>5, METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE AUTO',
CASCADE=>TRUE, DEGREE => 4);
it works correctly.
I already wrote other calling stored procedure methods in my java codes successfully, I simply used callable statement to call this particular stored procedure. All other methods are created stored procedures by Database admin, not the oracle system stored procedures.
Statement stmt = null;
StringBuffer sb = new StringBuffer();
CallableStatement cstmt = null;
sb.append("CALL DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'XXXXX', TABNAME=>'XXXXX', PARTNAME=>'XXXXX");
sb.append(yyyymm);
sb.append("', ESTIMATE_PERCENT=>5, METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE AUTO', CASCADE=>TRUE, DEGREE => 4)");
cstmt = this.conn.prepareCall(sb.toString());
cstmt.execute();
This gives me an error like this.
java.sql.SQLException: ORA-06576 : not a valid function or procedure name.
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:218)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:969)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1190)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3476)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4400)
at xxxxx.bo.batch.SYS010.SYS010.start(SYS010.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at framework.utility.classloader.DynamicClassLoader.execute(DynamicClassLoader.java:91)
at com.xxxxx.batch.module.Job.jobStart(Job.java:249)
at com.xxxxx.batch.module.Job.run(Job.java:300)
Could anyone give me any hint on what the real problem might be?
Does anyone have same error when calling DBMS_STATS from java source code?
Is this because of variables that I am passing within the function call?
I am using the same user account for oracle with java program and sqldeveloper.
Seems the "call" syntax for Oracle requires the statement to be wrapped in braces. See the examples provided with OracleCallableStatement. Note the {} surrounding the call statement (missing in the example above):
CallableStatement cs1 = conn.prepareCall( "{call proc (?,?)}" ) ;
The example also demonstrates bind variable usage.
Does it help if you replace your CALL with a PL/SQL block, i.e.
sb.append("BEGIN");
sb.append(" DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'XXXXX', TABNAME=>'XXXXX', PARTNAME=>'XXXXX");
sb.append(yyyymm);
sb.append("', ESTIMATE_PERCENT=>5, METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE AUTO', CASCADE=>TRUE, DEGREE => 4);");
sb.append("END;");
?
(Note the extra semicolon after the stored procedure call.)
you can call procedure from java code like this:
"select GATHER_TABLE_STATS('XXXX','XXXX','XXXX') from dual" to execute the it.
HTH.

Getting the Return Value from JDBC MSSQL

I'm connecting to SQL Server (2005) through Java using the Microsoft SQL Server JDBC Driver 2.0.
How do I get the return value from a stored procedure? I'm doing something like:
Connection connection = dataSource.getConnection()
CallableStatement proc = connection.prepareCall("{ call dbo.mySproc() }");
proc.execute();
Should I be using execute()? executeQuery()? executeUpdate()? None of these seem to return a return value by default but I'm not really sure how to get to it.
EDIT 1: To be clear, I know how to call stored procedures. This question is specifically about how to get the RETURN VALUE (as opposed to a Result Set). The Return Value is an integer that is usually generated when you execute a query with no Result Set or if you specifically state something like RETURN 0 in your SQL.
EDIT 2: executeUpdate() returns an int but this int is not the same as the Return Value. Also, an OUT parameter is not the same as a return value.
Bozho's 2nd revised answer was close but not quite there. It did lead me to the answer though.
Taking the code example I started with we end up with:
CallableStatement proc = connection.prepareCall("{ ? = call dbo.mySproc() }");
proc.registerOutParameter(1, Types.INTEGER);
proc.execute();
int returnValue = proc.getInt(1);
The key pieces here are the "? =" in front of the "call" in the prepareCall function which sets up a place for the return value and the registerOutputParameter. It has to be registered as an Integer, as the return value is always an int (at least in SQL Server, maybe it's different in other DBs). You therefore have to get it using getInt. I tested this method and it does work.
c.prepareCall("? = ..");
cs.execute();
String returnedValue = cs.getString(1);
(or the method of the appropriate type. You can use getObject alternatively)
From an old getting started tutorial
the getXXX methods in CallableStatement retrieve values from the OUT parameters and/or return value of a stored procedure.
(Btw, the links that were provided by Umesh had this sort of information.)

Categories

Resources