Верблюд обогащает вопрос синтаксиса SQL

Мне поручено создать маршрут Camel с использованием Camel версии 2.20.0, которая получает строку из CSV-файла, использует значение из этой строки в выражении SQL where, объединяет результаты и выводит их снова. Если я жестко закодировал идентификатор в операторе SQL, он работает нормально, если я пытаюсь использовать динамический URI, я получаю сообщение об ошибке.

Маршрут:

from("file:///tmp?fileName=test.csv")
.split()
.tokenize("\n")
.streaming()
.parallelProcessing(true)
.setHeader("userID", constant("1001"))
//.enrich("sql:select emplid,name from employees where emplid = '1001'",
.enrich("sql:select name from employees where emplid = :#userID",
     new AggregationStrategy() {
        public Exchange aggregate(Exchange oldExchange,
                                     Exchange newExchange)    {...

Как я уже сказал, если я раскомментирую строку с жестко закодированным 1001, он запрашивает БД и работает как положено. Однако, используя синтаксис ':#userID', я получаю ошибку Oracle:

java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist


    Message History
    ---------------------------------------------------------------------------------------------------------------------------------------
    RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
    [route3            ] [route3            ] [file:///tmp?fileName=test.csv                                                 ] [        43]
    [route3            ] [log5              ] [log                                                                           ] [         2]
    [route3            ] [setHeader2        ] [setHeader[userID]                                                             ] [         0]
    [route3            ] [enrich2           ] [enrich[constant{sql:select name from employees where emplid = :#userID] [        40]

Таблица явно присутствует, потому что она работает, когда значение жестко закодировано, поэтому оно имеет отношение к передаче динамического значения. Я пробовал множество вариантов передачи этой переменной внутри одинарных кавычек, используя значения из тела вместо заголовков и т. Д., Но пока не нашел рабочей комбинации, хотя видел много похожих, казалось бы, работающих примеров.,

Я включил трассировку, кажется, заголовок также установлен правильно:

o.a.camel.processor.interceptor.Tracer   :  >>> (route3) setHeader[userID, 1001] --> enrich[constant{sql:select name from employees where emplid = :#userID}] <<< Pattern:InOnly, Headers:{CamelFileAbsolute=true, CamelFileAbsolutePath=/tmp/test.csv, CamelFileLastModified=1513116018000, CamelFileLength=26, CamelFileName=test.csv, CamelFileNameConsumed=test.csv, CamelFileNameOnly=test.csv, CamelFileParent=/tmp, CamelFilePath=/tmp/test.csv, CamelFileRelativePath=test.csv, userID=1001}, BodyType:String, Body:1001,SomeValue,MoreValues

Что нужно изменить, чтобы сделать эту работу?

Я должен также отметить, что я попробовал этот подход, используя различные опции синтаксиса для ссылки на значение заголовка, без какой-либо удачи:

.enrich().simple("sql:select * from employees where emplid = :#${in.header.userID}").aggregate ...

2 ответа

Решение

Из документов:

Начиная с версии 2.16 и enrich, и pollEnrich поддерживают динамические конечные точки, которые используют выражение для вычисления URI, что позволяет использовать данные из текущего Exchange. Другими словами, все, что сказано выше, больше не применимо, и оно просто работает.

Поскольку вы используете 2.20, я думаю, вы можете попробовать этот пример:

from("file:///tmp?fileName=test.csv")
.split()
.tokenize("\n")
.streaming()
.parallelProcessing(true)
.setHeader("userID", constant("1001"))
//.enrich("sql:select emplid,name from employees where emplid = '1001'",
.enrich("sql:select name from employees where emplid = ':#${in.header.userID}'",
    new AggregationStrategy() {
        public Exchange aggregate(Exchange oldExchange,
                                    Exchange newExchange)    {...

Посмотрите тему Expression в docs для дальнейших примеров.

Подводя итог, выражение может быть:

"sql:select name from employees where emplid = ':#${in.header.userID}'"

РЕДАКТИРОВАТЬ:

Извините, я пропустил :# суффикс Вы могли видеть, что здесь работает модульный тест.

Просто позаботьтесь о типах столбцов. Если это целое число, вам не нужны кавычки.

Ура!

Из документов верблюда:

pollEnrich или enrich не имеют доступа к каким-либо данным из текущего Exchange, что означает, что при опросе он не может использовать ни один из существующих заголовков, которые вы могли установить на Exchange.

Рекомендуемый способ достижения того, что вы хотите, это вместо этого использовать recipientListтак что я предлагаю вам прочитать об этом.

Редактировать:

Как справедливо отметил Рикардо Занини в своем ответе, этого можно достичь с верблюдами версий 2.16 и выше. Поскольку ОП использует 2.20, мой ответ неверен.

Однако я оставлю свой ответ, но хочу отметить, что это действительно только в том случае, если вы используете более старую версию, чем 2.16.

Другие вопросы по тегам