Завел новый ярлык: "век живи - век учись". Причиной послужил следующий случай. Простая задачка: из смежной системы приходит идентификатор, по которому надо найти данные и добавить их в таблицу. База данных - Oracle. Казалось бы, что может быть проще. Есть, правда, одно отягчающее обстоятельство: приходит только идентификатор, а данные, которые он идентифицирует, могут лежать в одной из нескольких таблиц. Точнее, в одной из двух. То есть, указания, в какой таблице следует осуществлять поиск, нет. К счастью, идентификатор уникален, даже с учетом того факта, что исходных таблиц для поиска несколько - две.
Решений, как водится, может быть несколько. Без каких-либо задних мыслей было выбрано одно из - использовать объединение.
Решений, как водится, может быть несколько. Без каких-либо задних мыслей было выбрано одно из - использовать объединение.
select src from
(
select src from tbl_out where id = hextoraw(:id)
union
select src from tbl_in where id = hextoraw(:id)
)
Еще одно вводное условие: поле src в обеих таблицах - CLOB. Если после этого уточнения вы просекли фишку, идентифицировали проблему и знаете решение - примите мои уверения в совершеннейшем к вам почтении. И да, можете дальше не читать этот ламерский блог. Для всех остальных продолжу.
Запуск этой нехитрой конструкции приводит к возврату ошибки:
ORA
-00932: inconsistent datatypes: expected - got CLOB
Особенно меня порадовал оборот речи "expected - got CLOB". Драку заказывали? А, все равно, уплачено... получите... CLOB.
Профессор, конечно, лопух, но кое-какая аппаратура, то бишь, знания, при нем. Я знаю, что такую ошибку можно получить, если поле CLOB сравнивать с чем-то в where части SQL запроса. Происходит это из-за того, что (далее цитата из документации):
Large objects (LOBs) are not supported in comparison conditions".
Однако знания надо еще и применять, иногда, творчески. И тут, я, конечно, дал маху. Ведь что есть union? Это объединение двух наборов за исключением дубликатов. И вот в этом исключении и кроется корень проблемы. Чтобы понять, что нужно исключить из объединения наборов, надо понять, что является дубликатами, а для этого, по всей видимости, приходится сравнивать данные, а сравнивать LOB-ы, как мы знаем, нельзя. Небезызвестный сайт Ask Tom еще более категоричен.
Там же, кстати, содержится и рекомендация, как обойти проблему. И, после разбора причин ошибки, становится ясно, что этот обходной маневр вполне применим для решаемой задачи. Ведь по условию задачи, идентификатор обладает уникальностью не только в рамках конкретной таблицы, он уникален для всех задействованных таблиц. А раз так, то дубликатов быть не может, и union all вполне себе замена для union. Получаем:
select src from
(
select src from tbl_out where id = hextoraw(:id)
union all
select src from tbl_in where id = hextoraw(:id)
)
Этот запрос отрабатывает без малейших проблем. Вот такие вот дела.
Комментариев нет:
Отправить комментарий