我正在编写一个调用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相同的用户帐户。
答案 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。