четверг, 26 августа 2010 г.

Как узнать значение переменной ODI во время выполнения?

Как известно, в ETL процедурах ODI можно использовать переменные. Переменные эти различаются не только по типу возвращаемого результата, но и по тому, каким образом переменная (точнее, ее значение) взаимодействует с процессом ETL преобразований. По этому поводу я планирую написать отдельный пост, а пока хочу просто отметить, что переменные всех типов в ODI хранятся в коде ETL преобразования в виде строковой ссылки вида #Project.Variable.

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

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


Способ первый, использование raise exception
Создаем новую процедуру, назвав ее Raise_Exception. К ней создаем опцию с названием ERROR_TEXT. В процедуре делаем один шаг, который назовем Raise silent exception с технологией Java BeanShell и таким кодом:

throw new Exception("\n\n<%=odiRef.getOption("ERROR_TEXT")%>\n\n")

Выглядеть это будет примерно так:


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

Далее просто добавляем эту процедуру в пакет, в котором необходимо узнать значение переменной, и, в качестве параметра для опции ERROR_TEXT, передаем процедуре имя переменной для вывода:


Искать значение переменной необходимо на закладке Execution в свойствах шага Raise silent exception процедуры Raise_Exception. Выглядеть это будет примерно так:


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

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

<%=odiRef.getPrevStepLog("STEP_NAME")%>

,
а также добавляется вторая опция, указывающая наименование проекта.

Теперь, если мы расположим процедуру показа значения переменной в пакете сразу после ее обновления, мы можем не указывать отдельно наименование переменной как фактическое значение опции, функция getPrevStepLog сама вернет правильное значение.
Подробности по ссылке.

Вариант второй. Переменные сценария.
Этот метод основан на использовании недокументированного параметра функции GetSession, описание которого находится здесь. Создаем процедуру, в которой создаем шаг Show variables с технологией Oracle и ставим такой код:

/*
<%=odiRef.getSession( "SESS_PARAMS" )%>
*/


Далее используем эту процедуру так же, как описано выше, т.е. вставляем вызов в то место в пакете, где необходимо узнать значение переменных. А еще лучше сделать дополнительный шаг в модуле знаний (KM), чтобы видеть переменные, которые будут использоваться при работе ETL интерфейсов:


Результат, при использовании трех переменных, интерфейса и процедуры, которая показывает значения переменных, заданных при запуске сценария, выглядит так:


Обратите внимание, что результат отображается на закладке Description, а не Execution, как в предыдущем примере.

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

Небольшие выводы
Оба подхода имеют свои плюсы и свои минусы. В реальных проектах, скорее всего, будет возникать потребность задействовать и тот и другой механизм. Или их комбинацию. Например, доработать стандартные IKM для отображения значений переменных, или, что еще лучше, формировать полный текст SQL преобразования с уже подставленными значениями переменных для последующего анализа запроса в клиентском приложении СУБД.

3 комментария:

  1. Респект и уважуха!
    Сейчас я использую SAS Data Integration Studio в проекте, там это все делается автоматически. Плюс есть требования заказчика логировать все и вся, чтобы потом в случае разборок были аргументы.
    Но все требования я перекладывают на возможность реализации в ODI. Методы конечно жесткач, но хорошо что хоть такое есть.

    ОтветитьУдалить
  2. Небольшое дополнение: второй способ (при имплементации в KM) будет показывать значения переменных только если запускать сценарий. А вот при запуске просто интерфейса - это не работает.

    ОтветитьУдалить
  3. Скажу даже больше. Второй способ покажет в сценарии только те переменные, которые явным образом в этот сценарий передавались. Если же переменные просто имеют значения по умолчанию, или обновляются в пакете - odiRef.getSession("SESS_PARAMS" ) их не отобразит также.

    ОтветитьУдалить