четверг, 13 января 2011 г.

GetObjectName и другие способы обращения к таблице.

Приветствую.

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

Я планировал рассказать о двух методах для получения имен таблиц БД в процедурах. Эти методы отличаются от методов, которые используются в модулях знаний, так как модули знаний обычно применяются в интерфейсах, а, значит, можно пользоваться такими понятиями (и связанными с ними методами подстановки), как целевая таблица, или таблицы источники данных.

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

1. Используем метод подстановки getObjectName()

Документация пишет об этом методе следующее:

Форматы вызова:
  1. getObjectName(pMode, pObjectName, pLocation)
  2. getObjectName(pMode, pObjectName, pLogicalSchemaName, pLocation)
  3. getObjectName(pMode, pObjectName, pLogicalSchemaName, pContextName, pLocation)
  4. getObjectName(pObjectName, pLocation)
  5. getObjectName(pObjectName)
Все параметры строкового типа, возвращается тоже строка.

Возвращает полное наименование физического объекта, включая его сервер и схему. Параметр pMode определяет тип маски для подстановки в полное имя.
  • Первый формат вызова возвращает имя объекта в соответствие с текущей логической схемой и текущим контекстом.
  • Второй формат вызова возвращает имя объекта для текущего контекста и логической схемы переданной через параметр pLogicalSchemaName.
  • Третий формат - для логической схемы pLogicalSchemaName и контекста pContextName.
  • Четвертый формат - для текущей логической схемы и текущего контекста, с типом маски - локальная (pMode = "L").
  • Пятый формат такой же как четвертый, по-умолчанию используется значение pLocation = "D".

ПараметрОписание
pMode "L" - использовать локальный тип маски для построения имени объекта.
"R" - использовать удаленный тип маски.
    Примечание: при использовании удаленного типа, метод getObjectName всегда использует физическую схему установленную по-умолчанию для сервера данных.
pObjectName Строка, представляющая действительное имя ресурса (например, таблицу или файл). Имя объекта может предваряться кодом префикса, который будет заменен во время выполнения реальным значением, установленным для физической схемы.
pLogicalSchemaName Наименование логической схемы для объекта.
pContextName Наименование контекста для объекта.
pLocation "W" - Возвращает полное имя для объекта размещаемого во временной БД для физической схемы для заданных логической схемы и контекста.
"D" - Возвращает полное имя для объекта размещаемого в БД данных для физической схемы и для заданных логической схемы и контекста.

Небольшое пояснение к последнему параметру. При создании физической схемы в ODI задается две реальных БД. Одна - для данных, вторая - для создания временных таблиц, используемых при преобразованиях. Подробнее на странице инсталляции.


Префиксы

С помощью описанных ниже кодов, можно к имени объекта добавить некоторые префиксы, чтобы сгенерировать имена для временных объектов (временные таблицы с ошибочными строками, триггеры журнализации и т.п.).

КодОписание
%INT_PRF Префикс для временных таблиц интеграции (по-умолчанию "I$_")
%COL_PRF Префикс для временных таблиц загрузки (по-умолчанию "C$_")
%ERR_PRF Префикс для таблиц с ошибочными строками(по-умолчанию "E$_")
%JRN_PRF_TAB Префикс для временных таблиц журнализации (по-умолчанию "J$_")
%INT_PRF_VIE Префикс для временных представлений журнализации (по-умолчанию "JV$_")
%INT_PRF_TRG Префикс для триггеров журнализации (по-умолчанию "T$_")

Временные объекты обычно создаются во временной БД для физической схемы. Таким образом, для создания или обращения ко временному объекту необходимо указывать значение параметра pLocation равным W.


Примеры

КодРезультат
<%=odiRef.getObjectName("L", "SNP_ACTION", "MASTER-REP", "DEV", "W")%>tempdb.dbo.SNP_ACTION
<%=odiRef.getObjectName("L", "SNP_DATA", "MASTER-REP", "DEV", "D")%>db_snpm.dbo.SNP_DATA
<%=odiRef.getObjectName("R", "%ERR_PRFSNP_HOST", "MASTER-REP", "DEV", "W")%>.tempdb.dbo.E$_SNP_HOST
<%=odiRef.getObjectName("R", "SNP_LINK", "MASTER-REP", "DEV", "D")%>.db_snpm.dbo.SNP_LINK

Этот пример и примеры ниже взяты из инсталляции ODI на MS SQL Server, и выглядит физическая схема так:

[Image]

Второй способ - получить наименование БД (или схемы) и добавить к нему имя таблицы.

2a. Используем метод подстановки getSchemaName()


Форматы вызова:
  1. getSchemaName(pLogicalSchemaName, pLocation)
  2. getSchemaName(pLogicalSchemaName, pContextCode, pLocation)
  3. getSchemaName(pLocation)
  4. getSchemaName()
Все параметры строкового типа, возвращается тоже строка.

Возвращает физическое имя для временной БД или БД данных для заданной логической схемы.
  • В первом формате вызова возвращаемое наименование соответствует текущему контексту.
  • Второй формат вызова возвращает наименование схемы для заданного значения параметра pContextCode.
  • Третий формат вызова возвращает имя БД данных или временной БД для текущих значений контекста и логической схемы.
  • Четвертый формат возвращает имя БД данных для текущего контекста и логической схемы.

ПараметрОписание
pLogicalSchemaName Наименование логической схемы для объекта.
pContextCode Наименование контекста для объекта.
pLocation "W" - Возвращает имя временной БД физической схемы соответствующей паре контекст - логическая схема.
"D" - Возвращает имя БД данных физической схемы соответствующей паре контекст - логическая схема.

Примеры

КодРезультат
<%=odiRef.getSchemaName("MASTER-REP", "W")%&gt.SNP_ACTIONdbo.SNP_ACTION
<%=odiRef.getSchemaName("MASTER-REP", "DEV", "D")%&gt.SNP_DATAdbo.SNP_DATA
<%=odiRef.getSchemaName("W")%&gt.SNP_HOSTdbo.SNP_HOST
<%=odiRef.getSchemaName()%&gt.SNP_LINKdbo.SNP_LINK

2б. Используем метод подстановки getCatalogName()

Форматы вызова и параметры те же, что и для метода getSchemaName.

Примеры

КодРезультат
<%=odiRef.getCatalogName("MASTER-REP", "W")%&gt.SNP_ACTIONtempdb.SNP_ACTION
<%=odiRef.getCatalogName("MASTER-REP", "DEV", "D")%&gt.SNP_DATAdb_snpm.SNP_DATA
<%=odiRef.getCatalogName("W")%&gt.SNP_HOSTtempdb.SNP_HOST
<%=odiRef.getCatalogName()%&gt.SNP_LINKdb_snpm.SNP_LINK

Использование getCatalogName или getSchemaName применимо для тех СУБД, где полный путь к таблицам или другим объектам кодируется только через 2 параметра: наименование БД и объекта.

Обратите также внимание на то, что необходимо выбрать физическую схему по-умолчанию при наличии нескольких физических схем для одного дата сервера для корректной работы некоторых стандартных модулей знаний и метода getObjectName с параметром pMode = "R"

7 комментариев:

  1. Использую OdiFileWait дожидаюсь файла, передаю его на дальнейшую обработку. Как можно на самом первом этапе записать реальное имя файла в переменную?

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

    1. Процедура удаляет временный файл на диске
    2. Процедура создает отдельный файл при помощи утилит командной строки ОС, который содержит только список файлов из заданной директории.
    3. Интерфейс загружает данные из текстового файла (из пункта 2) в таблицу.
    4. По таблице делается рефреш переменной с выбором первого необработанного имени файла.
    5. Передается на обработку, где статус файла из таблицы (п. 4) обновляется на обработан.
    6. Переход на п. 4.

    ОтветитьУдалить
  3. А как в ODI считать в переменную весь текстовый файл?

    ОтветитьУдалить
  4. Вот так вот сходу - думаю, что никак.
    Идеология ELT инструмента, которым является ODI предусматривает что непосредственно работу по преобразованиям выполняет движок БД.

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

    Другой вариант - в процедуре создать шаг с джавой и уже при помощи подпрограммы на этом языке загрузить в память файл и что-то сделать с ним.

    ОтветитьУдалить
  5. Вот, тут есть начало обработки файлов в папке
    http://odiexperts.com/getting-one-or-several-unknown-files-from-a-directory/

    ОтветитьУдалить
  6. Спасибо, что отвечаете. Не знаю в какой теме лучше написать, поэтому рискну продолжить тут, хотя это и не относится к данной теме. Есть ли в ODI механизм преобразования одного комплексного файла в другой? У нас приходит файл примерно следующей структуры:
    FH,
    SB,xxx,yyy,zzz
    SB,aaa,bbb,ccc
    SF,
    RF,zzz
    RF,ccc
    FF
    Мы описали схему xsd, которая удачно разбирает этот файл, но затем нам надо собрать из распарсенных данных другой файл (для которого мы тоже описали схему xsd), представляющий из себя следующий вид и данные в котором после обработки должны встать следующим образом:
    IH;
    TR;мешанина;других;данных;zzz(взято из RF)
    DR;xxx;yyy;zzz
    TR;мешанина;других;данных;ccc(взято из RF)
    DR;aaa;bbb;ccc
    FT;
    Надеюсь описал понятно, что мы хотим. Можно конечно написать процедуры на jython'e, но не дает покоя, что мы просто не можем правильно применить инструментарий ODI.


    ОтветитьУдалить
  7. Я, к сожалению, не смог сейчас найти быстро пример, но в теории, это должно выглядеть как набор таблиц - datastore, которые преобразовываются при помощи интерфейсов.

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

    При этом также есть возможность использования встроенного SQL движка.
    Вот тут подробнее
    http://sonra.io/under-the-hood-of-the-sunopsis-memory-engine-part-1/

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