我是Camel的新手,我尝试处理SQL数据。如果SQL使用(select)完成,我尝试更新消耗的行,但我只是得到一个“错误的SQL语法”异常。
我使用Apache Camel SQL-Component,其中起始端点是sql select语句。要将它们标记为已消耗,我使用SQL-Component的onConsume
参数。在选择中,v_table
是原始表t_table
的视图,后续在更新中使用。因此id
和v_table
中行的t_table
是相同的。要更新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);
如果我执行此操作,我会遇到以下异常:
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
我尝试在数据库中使用test-id(例如“3”)手动执行更新,这样可行,因此通用SQL语法应该没问题。所以对我来说,Camel无法取代:#id
参数。
我添加了一个处理器,以检查选择的结果:
{ID=3, [...] CAMEL_IS_READ=0}
在这里我可以看到,选择成功捕获了必要的id
。我不明白为什么Camel无法用:#id
值3替换id
参数。有谁知道如何解决这个问题?我使用this和this作为粗略的示例/模板。或者这种做法一般是错误的吗?
答案 0 :(得分:1)
最后,通过使用sysdate
函数包围to_date()
语句,它对我有用:
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
可能是一种解决方案。如果您知道这种情况,您可能会暗示,如果具有此条件的所有行都通过camel传递,则可以更新此行。这与sysdate
一起使用,不需要id
占位符。这个解决方案的缺点是,它是有意义的,如果在同一时间添加了新的行,而这些行没有通过,它们也将在批处理完成后更新。所以我不推荐这个。
它也无法在Java中设置时间,如下所示:
String sqlUpdate = "update t_table date_checked = " + today + " where id = :#id";
如果您每天不重新开始路线,骆驼路线会在几天,几周或几年内保持活动状态。在这种情况下,驼峰路线将在启动时生成,在此之后,“今天”日期始终与此日期日期一致。因此,它将始终使用相同的日期进行数据库更新。