2011-11-12 41 views
1

Oracleストアド・プロシージャをコールする単純なJavaプログラムを作成していますが、コール可能な文では機能しません。 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コードに正常に書きました。私はこの特定のストアドプロシージャを呼び出すためにcallableステートメントを使用しました。他のすべてのメソッドは、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

上記のエラーを再現できる唯一の方法は、意図的にストアドプロシージャ名のスペルを間違えた場合です。 –

+0

はい、わかっています。私はすでにダブルチェックとトリプルチェックをしていましたが、タイプミスはありませんでした。また、私が実際に呼び出していたログファイルにも印刷されていますが、唯一の違いはSQLDeveloperのEXECの代わりにCALLです。私はEXECの代わりにCALLを使って同じSQLをSQLDeveloperで試してみましたが、同じエラーメッセージが表示されました。 – handicop

答えて

2

それは助けていますか?

(ストアドプロシージャの呼び出し後に、余分なセミコロンに注意してください。)

+0

ありがとう、ルーク、私は試して、それが行く方法を投稿します。 – handicop

+0

はい、動作します。ルークに感謝します。しかし、私はまだこの特定の声明のために電話が働いていないのだろうと思っています。 – handicop

-1

あなたは次のようにJavaコードからプロシージャを呼び出すことができます。

それを実行するために、 "デュアルからGATHER_TABLE_STATS( 'XXXX'、 'XXXX'、 'XXXX')を選択して"。

HTH。あなたは、PL/SQLブロックで、すなわち

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

をごCALLを交換する場合

+3

できません。 'DBMS_STATS.GATHER_TABLE_STATS'はプロシージャーであり、関数ではないため、このようにSQLから呼び出すことはできません。 –

3

Oracleのための「呼び出し」構文は、中括弧でラップされるステートメントを必要と思われます。 OracleCallableStatementで提供される例を参照してください。 {}は、(上記の例では欠落している)コール文を囲む注:

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

例では、バインド変数の使用を示します。