从java通过可调用语句调用存储过程时出错

时间:2011-11-12 08:03:11

标签: java sql oracle stored-procedures

我正在编写一个调用oracle存储过程的简单java程序,但它不适用于可调用语句。

当我在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);

它可以正常工作。

我已经成功地在我的java代码中编写了其他调用存储过程方法,我只是使用可调用语句来调用这个特定的存储过程。所有其他方法都是由数据库管理员创建的存储过程,而不是oracle系统存储过程。

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();

这给我一个这样的错误。

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)

有人能给我任何关于真正问题的暗示吗? 从java源代码调用DBMS_STATS时是否有任何人有相同的错误? 这是因为我在函数调用中传递的变量吗? 我使用与java程序和sqldeveloper的oracle相同的用户帐户。

3 个答案:

答案 0 :(得分:3)

似乎Oracle的“调用”语法要求将语句包装在大括号中。请参阅OracleCallableStatement提供的示例。请注意调用语句周围的{}(上例中缺少):

CallableStatement cs1 = conn.prepareCall( "{call proc (?,?)}" ) ;

该示例还演示了绑定变量的用法。

答案 1 :(得分:2)

如果用PL / SQL块替换CALL,即

,它会有帮助吗?
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;");

(注意存储过程调用后的额外分号。)

答案 2 :(得分:-1)

你可以从这样的java代码调用过程:

“从双重”选择GATHER_TABLE_STATS('XXXX','XXXX','XXXX')来执行它。

HTH。