DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Используем методы подстановки для изменения модулей знаний ODI.

Приветствую.
В прошлом году один из читателей этого блога задал по почте такой вопрос:
Как можно передать хинт на уровень запроса. К примеру, у нас есть интерфейс, он формирует запрос в LKM - шаг называется load data, но план не оптимальный, хочу улучшить, как я могу передать хинт в этот запрос?
Добавим немного практики в этот блог, и попробуем сделать два улучшения в один из модулей знаний, поставляемый вместе с ODI для MS SQL Server.
Перед началом внесения изменений в модули знаний, вам будет необходимо сделать дубликат выбранного модуля, чтобы все отладить и проверить не затрагивая других разработчиков:
Далее - переименовываем сдуплицированный IKM и установливаем его использование в тестовом интерфейсе. Конечно, когда вы будете вносить изменения в свои модули знаний, вы уже будете знать, как они работают, и в какие места необходимо добавить свой код, я же должен хотя бы приблизительно узнать последовательность действий, которые выполняет данный модуль знаний и попробовать его запуск с разными вариантами значений для опций:
Не уверен, что до конца понял логику выбранного модуля знаний, но для демонстрационных целей этого должно хватить. Итак...
Добавляем хинт в запрос
Я раньше этим не интересовался особо, но, оказывается, в MS SQL Server-е есть хинты. В связи с этим, я решил немного изменить задуманный пример, и реализовать один из видов хинтов, который будет подсказывать MS SQL Server-у необходимость использования индекса при выборке данных из таблицы.
В выбранном модуле знаний IKM MSSQL Incremental Update есть шаг (Create index on flow table), который создает для I$ таблицы индекс. Чтобы добавить использование этого индекса при переносе данных из временной I$ в целевую таблицу, необходимо найти все шаги в модуле знаний, в которых идет выборка из I$ таблицы, и которые вызываются на выполнение с теми же опциями, что и шаг создания индекса.
Нашлись следующие шаги:
Чтобы открыть, как в рисунке выше, несколько шагов модуля знаний (или процедуры, или несколько интерфейсов), необходимо выбрать из контекстного меню команду Edit in a New Window для каждого шага.
Теперь в шаг Update existing rows добавляем такой код:
OPTION (TABLE HINT(S, INDEX(", "W").substring(odiRef.getObjectName("L", "", "W").length())?>)))
А в шаг Insert new lines добавляем такой код:
OPTION (TABLE HINT(<%=odiRef.getTable("L","INT_NAME","W")%>, INDEX(", "W").substring(odiRef.getObjectName("L", "", "W").length())?>)))
Изменять эти шаги было не очень сложно, так как методы подстановки я использовал как раз те, которые создают индекс в шаге Create index on flow table выбранного модуля знаний.
Добавляем условие удаления данных перед загрузкой
Добавим новую опцию в модуль знаний и назовем ее DELETE_BY_CONDITION:
Через эту опцию мы будем передавать условие, по которому целевая таблица будет очищаться перед загрузкой новых данных:
Далее мы можем добавить новый шаг в модуль знаний, или изменить логику существующего шага Delete target table который удаляет все записи из целевой таблицы.
Создаем новый шаг, выбираем нужную технологию, и вводим следующий текст в поле Command:
<%if ( snpRef.getOption("DELETE_BY_CONDITION").equals("") ) { %>
<% } else { %>
DELETE FROM <%=snpRef.getTable("L","TARG_NAME","A")%>
WHERE <%=snpRef.getOption("DELETE_BY_CONDITION")%>
<% } %>
Если вы, как и я, сдуплицируете существующий шаг Delete target table - не забудьте на вкладке Options сдуплицированного шага установить признак безусловного выполнения (Allways Execute), а также тип счетчика в Delete если вы делаете новый шаг:
Результаты
Проверяем работу интерфейса без условия удаления:
С условием удаления:
Дизайнер
Оператор
Хочу еще добавить такой совет. При изменениях в модулях знаний, иногда удобнее, особенно при отладке кода с методами подстановки, создать в начале модуля несколько тестовых шагов выполнения. В первом шаге можно будет пробовать вызовы методов, в нем устанавливается опция игнорирования ошибок, а второй шаг просто завершает работу интерфейса с ошибкой:







jAntivirus