1

我是 Camel 的新手,我尝试处理 SQL 数据。如果 SQL 消费(选择)完成,我会尝试更新消费的行,但我只是得到一个“错误的 SQL 语法”异常。

我使用 Apache Camel SQL-Component,其中起始端点是 sql select 语句。要将它们标记为已使用,我使用SQL-ComponentonConsume的参数。在选择中,是原始表的视图,之后在更新中使用。所以和中的一行是一样的。为了不更新 中的所有行,我使用 where 条件。v_tablet_tableidv_tablet_tablet_tablewhere 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 语法应该没问题。所以在我看来,骆驼不能替换:#id参数。

我添加了一个处理器,以检查选择的结果:

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

在这里我可以看到,选择成功地抓住了必要的id. 我不明白为什么 Camel 不能:#id用值 3 替换参数id。有谁知道如何解决这个问题?我用这个这个作为一个粗略的例子/模板。还是这种方法总体上是错误的?

4

1 回答 1

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可能是一个解决方案。如果您知道条件,您可能会暗示,如果具有此条件的所有行都通过骆驼,则可以更新此行。这与占位符一起使用sysdate并且不需要id占位符。这种解决方案的缺点是,它是隐含的,如果同时添加新行,哪些骆驼没有通过,它们也将在批处理完成后更新。所以我不能推荐这个。

在 Java 中设置时间也不起作用,如下所示:

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

如果你不是每天都重新开始你的路线,骆驼路线会在几天、几周或几年内处于活跃状态。在这种情况下,骆驼路线将在启动时生成,此后,“今天”日期始终与这一天日期固定。因此它将始终使用相同的日期进行数据库更新。

于 2016-09-15T12:37:07.393 回答