人々がこのメッセージを症状として表示するWebページが多数あります(SQLERRMC
の後の値とドライバーレベルは変化します):
DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=M51Dev.CUSTOMER, DRIVER=3.61.65
いくつかの here on StackOverflow を含む。
エラーコードは、オブジェクト(ほとんど常にテーブル)が見つからないことを意味し、SQLERRMC
パラメーターの値には問題のオブジェクトの名前が含まれています。私が見つけることができるこの他のすべての事例では、解決策は、テーブル名をスキーマ名で修飾する必要があるだけでした。ただし、上記の行からわかるように、ここではそうではありません。スキーマはM51Dev
、テーブルはCUSTOMER
であり、両方とも存在します。
環境は、古いXPマシン上のDB2 9.7.300.3885で、Windows Server 2003 R2で実行されているWebSphere Application Server(この特定のケースでは7.0.0.31ですが、どういうわけか関係があると思います)です。データソースはWASで定義され、JNDI経由で取得され、アプリケーションはJavaで記述され、SQLがSpringのJdbcTemplate
s経由でJDBCを使用して実行されます。
WASのデータソース定義には、currentSchema
というカスタムプロパティが含まれています。これは、M51Dev
。
これは、SQLの関連する行です(すべてのテーブルで同じ症状が発生するため、その1つです)。
SELECT rundateOverride FROM customer WHERE customerId=1
そして、スタックトレースからの抜粋です。助けがあればもっと提供できます。
bad SQL grammar [SELECT rundateOverride FROM customer WHERE customerId=1]; nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=M51Dev.CUSTOMER, DRIVER=3.61.65
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.Java:233)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.Java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:406)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:455)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:463)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.Java:471)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.Java:476)
at com.misys.meridian.runtime.userPromptable.SchedulerService.refreshMarketCentreSystemDates(SchedulerService.Java:1539)
at com.misys.meridian.runtime.userPromptable.SchedulerService.performService(SchedulerService.Java:270)
at com.misys.meridian.runtime.userPromptable.SchedulerService.Prompt(SchedulerService.Java:175)
at com.misys.meridian.runtime.userPromptable.GenericDelegate.process(GenericDelegate.Java:95)
at org.Apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.Java:61)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.Java:99)
at org.Apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.Java:90)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.Java:99)
at org.Apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.Java:90)
at org.Apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.Java:71)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.Java:99)
at org.Apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.Java:90)
at org.Apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.Java:91)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.Java:333)
at org.Apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.Java:223)
at org.Apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.Java:45)
at org.Apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.Java:90)
at org.Apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.Java:304)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.Pipeline.process(Pipeline.Java:117)
at org.Apache.camel.processor.Pipeline.process(Pipeline.Java:80)
at org.Apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.Java:73)
at org.Apache.camel.processor.Pipeline.process(Pipeline.Java:117)
at org.Apache.camel.processor.Pipeline.access$100(Pipeline.Java:43)
at org.Apache.camel.processor.Pipeline$1.done(Pipeline.Java:135)
at org.Apache.camel.processor.ThreadsProcessor$ProcessCall.run(ThreadsProcessor.Java:56)
at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:450)
at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:314)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:149)
at Java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.Java:906)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:929)
at Java.lang.Thread.run(Thread.Java:761)
Caused by: com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=M51Dev.CUSTOMER, DRIVER=3.61.65
at com.ibm.db2.jcc.am.ed.a(ed.Java:676)
at com.ibm.db2.jcc.am.ed.a(ed.Java:60)
at com.ibm.db2.jcc.am.ed.a(ed.Java:127)
at com.ibm.db2.jcc.am.gn.c(gn.Java:2554)
at com.ibm.db2.jcc.am.gn.d(gn.Java:2542)
at com.ibm.db2.jcc.am.gn.a(gn.Java:2034)
at com.ibm.db2.jcc.t4.cb.g(cb.Java:140)
at com.ibm.db2.jcc.t4.cb.a(cb.Java:40)
at com.ibm.db2.jcc.t4.q.a(q.Java:32)
at com.ibm.db2.jcc.t4.rb.i(rb.Java:135)
at com.ibm.db2.jcc.am.gn.gb(gn.Java:2005)
at com.ibm.db2.jcc.am.gn.a(gn.Java:3023)
at com.ibm.db2.jcc.am.gn.a(gn.Java:667)
at com.ibm.db2.jcc.am.gn.executeQuery(gn.Java:651)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeQuery(WSJdbcStatement.Java:999)
at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.Java:440)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:395)
... 40 more
背景として、これは複数のデータベースプラットフォームをサポートする銀行業務アプリケーションです。 Oracle、MS SQL Server、DB2 for System iのさまざまなバージョンを使用して、長年の経験があります。ただし、DB2 LUWの使用は比較的新しいものです。それでも、少なくとも同じマシン上にWASとDB2がある場合、私の同僚の何人かは上記の構成が機能しています。
そして、WASを搭載したマシンでSQLクライアントを実行し、同じパラメーターを使用して問題のデータベースに接続し、SET SCHEMA M51Dev
およびテーブル名を修飾しません。JDBC/ JNDI環境を最も厳密にエミュレートすると思います。
答えは大文字と小文字の区別です。
この答えは、実際には コメント の mustaccio によって提供されましたが、回答として追加したくないようです。 @mustaccioにこのメッセージが表示された場合は、独自の回答を追加してください。受け入れます。
とにかく、WASは、「カスタムプロパティ」セクションで指定した値を効果的に引用符で囲んでいるように見えます。 currentSchema
プロパティにM51Dev
と入力しましたが、"M51Dev"
としてDB2に送信されていました。しかし、DB2はスキーマ名をM51DEV
として保存していました。もちろん、これらは2つの異なる値として認識されます。
プロパティ値にM51DEV
を指定すると、問題が修正されました。