首页 > 解决方案 > Apache Camel 2.18 中的 IN 子句

问题描述

我正在尝试在路由中执行 sql 删除语句。该查询包含一个 IN 子句,我想将一组值传递给 IN 子句。我正在使用 camel-core & camel-jdbc 2.18.1 和 camel-sql 2.18.0

from("direct:deleteRoute").setBody(simple("DELETE FROM TABLE_NAME WHERE ID IN (:#in:idSet)")).to(Constants.JDBC_DATA_SOURCE).end();

idSet 的值通过路由的键在交换的标头中传递,idSet该路由调用direct:deleteRoute.

但是当我执行时,我得到以下异常。

java.sql.SQLException: A syntax error has occurred.
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:408)
    at com.informix.jdbc.IfxSqli.a(IfxSqli.java:3132)
    at com.informix.jdbc.IfxSqli.D(IfxSqli.java:3412)
    at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2325)
    at com.informix.jdbc.IfxSqli.receiveMessage(IfxSqli.java:2250)
    at com.informix.jdbc.IfxSqli.executeExecute(IfxSqli.java:2153)
    at com.informix.jdbc.IfxSqli.executeExecute(IfxSqli.java:2133)
    at com.informix.jdbc.IfxResultSet.b(IfxResultSet.java:362)
    at com.informix.jdbc.IfxStatement.a(IfxStatement.java:1144)
    at com.informix.jdbc.IfxStatement.executeImpl(IfxStatement.java:1120)
    at com.informix.jdbc.IfxStatement.c(IfxStatement.java:866)
    at com.informix.jdbc.IfxStatement.execute(IfxStatement.java:784)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
    at com.sun.proxy.$Proxy105.execute(Unknown Source)
    at org.apache.camel.component.jdbc.JdbcProducer.doCreateAndExecuteSqlStatement(JdbcProducer.java:220)
    at org.apache.camel.component.jdbc.JdbcProducer.createAndExecuteSqlStatement(JdbcProducer.java:125)
    at org.apache.camel.component.jdbc.JdbcProducer.processingSqlBySettingAutoCommit(JdbcProducer.java:86)
    at org.apache.camel.component.jdbc.JdbcProducer.process(JdbcProducer.java:67)
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:117)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
    at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:192)
    at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: java.sql.SQLException: null
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:408)
    at com.informix.jdbc.IfxSqli.D(IfxSqli.java:3417)
    ... 53 common frames omitted

标签: apache-camelcamel-sql

解决方案


此堆栈跟踪来自camel-jdbc组件。该组件使用标准的 JDBC API,因此它受到了一些限制。其中之一是,您不能将集合作为单个参数传递
在 Camel 中,您可以实现自定义JdbcPrepareStatementStrategy,将其注册到 uri 参数 prepareStatementStrategy 以提供解析查询的自定义逻辑,但我不建议这样做。这会导致很多陷阱。

更好地使用camel-sql组件,它spring-jdbc从 Apache Camel 2.17 开始本机使用并允许这样做。

带有常量准备语句的示例:

from("direct:deleteIds")
        .to("sql:DELETE FROM TABLE_NAME WHERE ID IN (:#in:idSet)");

从正文创建的语句示例:

from("direct:deleteIds")
        .setBody(simple("DELETE FROM TABLE_NAME WHERE ID IN (:?in:idSet)")) // Note questionmark here for specifying parameter. This is difference against query in uri.  
        .to("direct:executeQuery");

from("direct:executeQuery")
        .setHeader(SqlConstants.SQL_QUERY, body())
        .to("sql:dummy?dataSource=#datasource");

推荐阅读