2016-08-19 15 views
1

私はCamelで新しく、SQLデータを処理しようとしています。 SQLの消費(選択)が完了すると、消費された行を更新しようとしますが、「不良なSQL文法」例外が発生します。Apache Camel SQLコンポーネントで消費されたSQL行のみを更新するには?

私はApache Camel SQLコンポーネントを使用します。ここで、開始エンドポイントはSQL SELECT文です。それらを消費されたものとしてマークするには、SQL-ComponentonConsumeパラメータを使用します。選択では、v_tableは元のテーブルt_tableのビューであり、後で更新で使用されます。したがって、v_tablet_tableの行のidは同じです。 t_tableのすべての行を更新するのではなく、where id = :#idとwhere条件を使用します。

String sqlSelect = "select * from v_table where camel_is_read = 0"; 
String sqlUpdate = "update t_table set camel_is_read = 1, date_checked = sysdate where id = :#id"; 
from("sql:"+sqlSelect+"?dataSource=myDataSource&onConsume="+sqlUpdate) 
.process(new Processor() { 
    public void process(Exchange exchange) throws Exception { 
     System.out.println(exchange.getIn().getBody().toString()); 
    } 
})      
.errorHandler(deadLetterChannel("direct:moveFailedOut").useOriginalMessage()) 
.bean("orderToJms") 
.to(jmsURI) 
.bean("validate") 
.to(ftpOut); 

私はこれを実行すると、私はfollwoing例外を取得:

WARN Error executing onConsume/onConsumeFailed query update t_table set camel_is_read = 1, date_checked = sysdate where id = :?id. Caused by: [org.springframework.jdbc.BadSqlGrammarException - PreparedStatementCallback; bad SQL grammar [update t_table set camel_is_read = 1, date_checked = sysdate where id = ?]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00904: "YSDATEHERE": ungültiger Bezeichner 
] 
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [update t_table set camel_is_read = 1, date_checked = sysdate where id = ? exception is java.sql.SQLSyntaxErrorException: ORA-00904: "YSDATEHERE": ungültiger Bezeichner 

    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:237) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617) 
    at org.apache.camel.component.sql.DefaultSqlProcessingStrategy.commit(DefaultSqlProcessingStrategy.java:46) 
    at org.apache.camel.component.sql.SqlConsumer.processBatch(SqlConsumer.java:195) 
    at org.apache.camel.component.sql.SqlConsumer$1.doInPreparedStatement(SqlConsumer.java:118) 
    at org.apache.camel.component.sql.SqlConsumer$1.doInPreparedStatement(SqlConsumer.java:91) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617) 
    at org.apache.camel.component.sql.SqlConsumer.poll(SqlConsumer.java:91) 
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) 
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:724) 
Caused by: java.sql.SQLSyntaxErrorException: ORA-00904: "YSDATEHERE": ungültiger Bezeichner 

私はテスト-ID(例えば「3」)と、データベースに手動で更新を実行しようとした、働きます、一般的なSQL文法はうまくいくはずです。ですから、Camelは:#idのパラメータを置き換えることはできません。

私は選択の結果を確認するために、プロセッサを追加しました:

ここ
{ID=3, [...] CAMEL_IS_READ=0} 

私は選択が正常に必要なidをcatchedことを、見ることができます。私はキャメルがidの値で:#idパラメータを置き換えることができない理由を理解していません。誰もこの問題を解決する方法を知っていますか?私は大まかな例/テンプレートとしてthisthisを使用しました。あるいは、このアプローチは一般的に間違っていますか?

+0

sysdateは大文字である必要がありますか? –

+0

こんにちは@ClausIbsen、あなたの応答をありがとう(と私はあなたの本が好きです:)。 sysdateの代わりにSYSDATEを使って実際に試しましたが、効果がありませんでした。私はまた、全体の更新文をOracleデータベースで直接試してみました。 idパラメータなしでも動作します(しかし、それは目標ではなく、処理された行を更新したいだけです)。 – Zeussi

+0

どんなバージョンのCamel。アップグレードを試すことができます。 –

答えて

1

最後に、それはto_date()機能をsysdate文を囲むことにより、私の作品:

String sqlSelect = "select * from v_table where camel_is_read = 0"; 
String sqlUpdate = "update t_table set camel_is_read = 1, date_checked = to_date(sysdate) where id = :#id"; 
from("sql:"+sqlSelect+"?dataSource=myDataSource&onConsume="+sqlUpdate) 
.process(new Processor() { 
    public void process(Exchange exchange) throws Exception { 
     System.out.println(exchange.getIn().getBody().toString()); 
    } 
})      
.errorHandler(deadLetterChannel("direct:moveFailedOut").useOriginalMessage()) 
.bean("orderToJms") 
.to(jmsURI) 
.bean("validate") 
.to(ftpOut); 

いくつかのノートを、動作しないものを/(私の意見では)良いアイデアではなく、多分あなたが保存されます時間:
状況によっては、onConsumeBatchCompleteが解決策になります。条件を知っていれば、この条件のすべての行がラクダを通過すると、この行を更新することができます。これはsysdateと一緒に動作し、idプレースホルダは必要ありません。この解決方法の欠点は、それが当てはまることであり、同時に新しい行が追加された場合、どのラクダが渡されなかったかは、バッチが完了した後に更新されることです。だから私はこれをお勧めできません。

また、このように、Javaでの時間を設定することは動作しません:

String sqlUpdate = "update t_table date_checked = " + today + " where id = :#id"; 

あなたが毎日あなたのルートを再起動しない場合は、ラクダのルートがアクティブになって数日、数週間または数年にわたって。この場合、ラクダルートはスタートアップ時に生成され、その後に、今日の日付で常に「今日」の日付が修正されます。したがって、データベースの更新には常に同じ日付が使用されます。

関連する問題