Как выбрать отчетливое в esql?
У меня есть подпоток в esql (IBM Websphere Message Broker), где мне нужно добиться чего-то похожего на select distinct
функциональность.
Немного предыстории: у меня есть таблица в базе данных Oracle group_errcode_ref
, Эта таблица представляет собой фиксированную ссылку / отображение ERROR_CODE
а также ID
, ERROR_CODE
уникален, но ID
может быть продублировано Например, коды ошибок 4000 и 4001 могут быть связаны с идентификатором 1.
В моем потоке esql у меня есть массив кодов ошибок, которые меняются в зависимости от текущих данных, поступающих в поток.
Итак, мне нужно взять массив кодов ошибок и выбрать ID
для всех кодов ошибок в массиве из моей таблицы group_errcode_ref
Что у меня сейчас:
declare db rows;
set db.rows[] = (select d.ID from Database.group_errcode_ref as d where d.ERROR_CODE in (select D from errCodes.Code[] as D);
errCodes
массив кодов ошибок из ввода. row
это массив всех идентификаторов, которые соответствуют кодам ошибок.
Это нормально, но я хочу удалить дубликаты из db.rows[]
массив.
Я не уверен, что лучший способ сделать это в esql, но он не поддерживает distinct
, group by
, или же order by
2 ответа
Если вы используете оператор PASSTHRU, то поддерживаются все функциональные возможности вашего менеджера баз данных, а также такие разные.
Единственное, что вам нужно преодолеть, это то, что вы не можете напрямую смешивать запросы к базе данных и к дереву сообщений в PASSTHRU, все, что вы передаете ему, направляется непосредственно в базу данных.
Итак, ваше оригинальное решение будет выглядеть примерно так:
set db.rows[] = PASSTHRU 'select distinct d.ID from SCHEMA.group_errcode_ref as d where d.ERROR_CODE in ' || getErrorCodesFromInput(errCodes) TO Database.DSN1;
Здесь getErrorCodesFromInput - это функция, которая возвращает символ, который содержит коды ошибок в вашем вводе, правильно отформатированные для запроса, например (ec1, ec2, ...)
Моя работа вокруг закончилась тем, что я не делал выборочный отчет или сортировку вообще, кроме другой работы вокруг.
По сути, я перебираю весь массив ERROR_CODE, затем запрашиваю идентификатор, соответствующий коду error_code, затем выбираю count(*) в таблице, в которую я их вставляю.
Это работает для моего конкретного приложения только потому, что я вставляю пары ID/Issue.
В основном это выглядит так:
for x as errs.Error[] do
declare db row;
set db.rows[] = passthru('select ID from my_static_map_table where error_code = ?;' values(x.Code));
declare db2 row;
set db2.rows[] = passthru('select count(*) from my_table_2 where guid = ? and id = ?;' values(guid, db.ID));
if db2.COUNT == 0 then
-- Here I do an insert into my_table_2 with ID and a few other values
end if;
end for;
Не совсем правильный ответ, но он работает для моего конкретного приложения. По сути, перебирайте каждый код ошибки и выбирайте по одному, а не отправляйте весь массив. Затем выполните вставку в другую базу данных, избегая дублирования другим выбором, чтобы увидеть, была ли она уже вставлена.
Я все еще буду ждать неделю, чтобы выяснить, есть ли лучший ответ, и приму его.
ОБНОВИТЬ
Я изменил свой код, чтобы он соответствовал решению Attila - что намного лучше и что я искал изначально
Единственное, что я добавлю, это моя функция, которая форматирует коды ошибок - что действительно очень просто:
create function FlattenErrorCodesArray(in err row) returns char begin
declare idx int 1;
declare ret char;
for x as errs.Error[] do
if idx = 1 then
set ret = '(' || cast(x.Code as char);
else
set ret = ret || ',' || cast(x.Code as char);
end if;
set idx = idx + 1;
end for;
set ret = ret || ')';
end;