пятница, 4 февраля 2011 г.

Используем методы подстановки для изменения модулей знаний 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(<?=odiRef.getObjectName("L", "IX_<%=odiRef.getTargetTable("RES_NAME")%>", "W").substring(odiRef.getObjectName("L", "", "W").length())?>)))


А в шаг Insert new lines добавляем такой код:

OPTION (TABLE HINT(<%=odiRef.getTable("L","INT_NAME","W")%>, INDEX(<?=odiRef.getObjectName("L", "IX_<%=odiRef.getTargetTable("RES_NAME")%>", "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 если вы делаете новый шаг:


Результаты

Проверяем работу интерфейса без условия удаления:


С условием удаления:

Дизайнер

Оператор

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

Комментариев нет:

Отправить комментарий