Предложение IN в Apache Camel 2.18

Я пытаюсь выполнить оператор удаления sql на маршруте. Запрос содержит предложение IN, и я хочу передать набор значений в предложение IN. Я использую верблюжье ядро ​​и верблюд-jdbc 2.18.1 и верблюд-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

person Ronald James    schedule 07.05.2018    source источник
comment
Не могли бы вы поделиться, что находится в переменной Constants.JDBC_DATA_SOURCE? Поскольку из stacktrace кажется, что это компонент JDBC, но вы использовали синтаксис параметра для компонента SQL. Компонент SQL использует :# для привязки параметров, компонент JDBC использует :?. И еще одно замечание: никогда не смешивайте версии зависимостей, это может привести к непредсказуемому поведению. Всегда используйте все компоненты в той же версии, что и Apache Camel.   -  person Bedla    schedule 07.05.2018


Ответы (1)


Эта трассировка стека получена из компонента 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");
person Bedla    schedule 07.05.2018
comment
Спасибо @Bedla. Я работаю над весенней загрузкой, и если я продолжу использовать второй пример, каким должно быть значение для #datasource. Это имя компонента, представляющего DataSource. - person Ronald James; 08.05.2018
comment
#datasource — это ссылка для поиска источника данных в реестре (обычно это имя Spring Bean). - person burki; 08.05.2018