Мысль о переменных ODI

Это мой первый вклад на Medium под брендом Red Pill Analytics. Я надеюсь, что буду поддерживать высокие стандарты моих коллег.

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

Это может показаться простым: мы присоединяем активные записи к устаревшим, чтобы создать расширенный набор данных. Однако существует проблема с этим подходом (или, по крайней мере, с базами данных Oracle, где доступ к устаревшей системе осуществляется через ссылку на базу данных), которая приводит к тому, что подсказки сайта игнорируются в операторах вставки. В итоге мы получаем ужасный план казни, упомянутый здесь Джонатаном Льюисом. Да, есть решения, такие как подход с конвейерной таблицей, который я разработал для этого клиента, но здесь мне нужно было что-то сделать полностью в ODI.

Иногда нам нужно сделать шаг назад и подумать: «Правильно ли использовать соединение?» Могу ли я закодировать это другим способом, который не требует от меня написания функции, которую мне нужно будет поддерживать в базе данных?

ODI дает нам два основных способа ограничения объема данных, которые мы возвращаем, объединение и фильтрация; есть ли способ использовать ФИЛЬТР для ограничения наших данных? Очевидно, что мы можем жестко закодировать фильтры, такие как «data1.STATUS=‘Active’», но что, если нам нужна гибкость для динамического выбора значения нашего статуса. Это, конечно, просто для одного значения — мы используем переменную в фильтре. Но что, если нам нужно отфильтровать с помощью списка IN, например, «data_source.key IN(1,2,5,7,99,2345)»? как мы поставляем переменное количество значений? Вот один из методов, который мы можем использовать.

Oracle 11gR2 представила в базе данных функцию LISTAGG. Эта функция в основном объединяет несколько строк данных в одну строку. В нашем случае мы хотим сгенерировать список значений, разделенных запятыми, которые мы можем вставить в наше выражение фильтра в ODI. Обновление переменной — это простой SELECT LISTAGG… из нашей исходной таблицы списка. Наше выражение фильтра в ODI будет выглядеть примерно так

Документация Oracle для LISTAGG имеет синтаксис. Для нашего использования нам нужно указать разделитель между элементами. Для числовых совпадений это должна быть запятая ',', это немного сложнее для строковых совпадений, здесь нам нужно заключать в кавычки каждый элемент, поэтому нам нужно будет заключать в кавычки нашу запятую - нам также нужно заключать в кавычки переменную в фильтре ODI. условие, так что мы поставляем начальные и конечные кавычки

Например, мы могли бы определить обновление для переменной Filter_List как

SELECT LISTAGG(TO_CHAR(PRODUCT_KEY) ,’,’) WITHIN GROUP (ORDER BY PRODUCT_KEY) from PRODUCTS_LOADED

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

Конечно, у этого подхода есть ограничения. У нас может быть только конечный размер символьной переменной ODI, и это ограничение на размер списка в базе данных. Но для выборок разумного размера этот подход работает хорошо.

Спасибо, что прочитали этот пост в блоге Red Pill Analytics. Больше блогов наших замечательных авторов вы можете найти здесь. Узнайте больше о Red Pill Analytics на redpillanalytics.com.