2016-08-19 26 views
1

我是駱駝新手,我嘗試處理SQL數據。如果SQL消耗(選擇)完成,我嘗試更新消費的行,但我只是得到一個「錯誤的SQL語法」異常。如何使用Apache Camel SQL組件更新僅消耗的SQL行?

我使用Apache Camel SQL-Component,其中起始端點是一個sql select語句。爲了將它們標記爲已消耗,我使用SQL-ComponentonConsume參數。在選擇中,v_table是原始表t_table的視圖,在更新後使用。所以v_tablet_table中的一排id是一樣的。要更新t_table中的所有行,我使用where條件與where id = :#id

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語法應該沒問題。所以在我看來,駱駝不能取代:#id參數。

我添加了一個處理器,檢查選擇的結果:

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

在這裏,我可以看到,選擇成功擦肩而過,必要id。我不明白爲什麼駱駝不能取代:#id參數與id值3.有誰知道如何解決這個問題?我使用thisthis作爲粗略示例/模板。或者這種方法一般是錯誤的?

+0

sysdate應該是大寫嗎? –

+0

嗨@ClausIbsen,謝謝你的回覆(我喜歡你的書:)。我其實用SYSDATE而不是sysdate來嘗試它,但它沒有顯示效果。我也直接在我的oracle數據庫中嘗試了整個更新語句,它在哪裏工作。它也沒有id參數(但這不是目標,我只想更新處理的行)。 – Zeussi

+0

什麼版本的駱駝。你可以嘗試升級。 –

回答

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

如果不重新啓動您的路線,每天駱駝的路線是活躍在幾天,幾周或數年。在這種情況下,駱駝路線將在啓動時生成,此後,「今天」日期始終與當天的日期一致。所以它會一直使用相同的日期進行數據庫更新。