При подготовке сообщений в блог начальная идея иногда трансформируется в нечто совершенно другое. Более того, иногда, изучив документацию и примеры - понимаешь, что некоторые вещи, которые раньше делал, делал понимая не до конца, хотя и с правильными результатами.
Я планировал рассказать о двух методах для получения имен таблиц БД в процедурах. Эти методы отличаются от методов, которые используются в модулях знаний, так как модули знаний обычно применяются в интерфейсах, а, значит, можно пользоваться такими понятиями (и связанными с ними методами подстановки), как целевая таблица, или таблицы источники данных.
Методы подстановки, о которых идет речь ниже, могут быть использованы как в процедурах, так и в модулях знаний, при необходимости. Например, если во всех модулях знаний использовать некоторую общую таблицу, которая явным образом не включается в интерфейс ODI, обратиться к этой таблице (получить ее полное имя) можно описанными ниже способами.
1. Используем метод подстановки getObjectName()
Документация пишет об этом методе следующее:
Форматы вызова:
- getObjectName(pMode, pObjectName, pLocation)
- getObjectName(pMode, pObjectName, pLogicalSchemaName, pLocation)
- getObjectName(pMode, pObjectName, pLogicalSchemaName, pContextName, pLocation)
- getObjectName(pObjectName, pLocation)
- getObjectName(pObjectName)
Возвращает полное наименование физического объекта, включая его сервер и схему. Параметр pMode определяет тип маски для подстановки в полное имя.
- Первый формат вызова возвращает имя объекта в соответствие с текущей логической схемой и текущим контекстом.
- Второй формат вызова возвращает имя объекта для текущего контекста и логической схемы переданной через параметр pLogicalSchemaName.
- Третий формат - для логической схемы pLogicalSchemaName и контекста pContextName.
- Четвертый формат - для текущей логической схемы и текущего контекста, с типом маски - локальная (pMode = "L").
- Пятый формат такой же как четвертый, по-умолчанию используется значение pLocation = "D".
Параметр | Описание |
---|---|
pMode | "L" - использовать локальный тип маски для построения имени объекта. "R" - использовать удаленный тип маски.
|
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, и выглядит физическая схема так:
Второй способ - получить наименование БД (или схемы) и добавить к нему имя таблицы.
2a. Используем метод подстановки getSchemaName()
Форматы вызова:
- getSchemaName(pLogicalSchemaName, pLocation)
- getSchemaName(pLogicalSchemaName, pContextCode, pLocation)
- getSchemaName(pLocation)
- getSchemaName()
Возвращает физическое имя для временной БД или БД данных для заданной логической схемы.
- В первом формате вызова возвращаемое наименование соответствует текущему контексту.
- Второй формат вызова возвращает наименование схемы для заданного значения параметра pContextCode.
- Третий формат вызова возвращает имя БД данных или временной БД для текущих значений контекста и логической схемы.
- Четвертый формат возвращает имя БД данных для текущего контекста и логической схемы.
Параметр | Описание |
---|---|
pLogicalSchemaName | Наименование логической схемы для объекта. |
pContextCode | Наименование контекста для объекта. |
pLocation | "W" - Возвращает имя временной БД физической схемы соответствующей паре контекст - логическая схема. "D" - Возвращает имя БД данных физической схемы соответствующей паре контекст - логическая схема. |
Примеры
Код | Результат |
---|---|
<%=odiRef.getSchemaName("MASTER-REP", "W")%>.SNP_ACTION | dbo.SNP_ACTION |
<%=odiRef.getSchemaName("MASTER-REP", "DEV", "D")%>.SNP_DATA | dbo.SNP_DATA |
<%=odiRef.getSchemaName("W")%>.SNP_HOST | dbo.SNP_HOST |
<%=odiRef.getSchemaName()%>.SNP_LINK | dbo.SNP_LINK |
2б. Используем метод подстановки getCatalogName()
Форматы вызова и параметры те же, что и для метода getSchemaName.
Примеры
Код | Результат |
---|---|
<%=odiRef.getCatalogName("MASTER-REP", "W")%>.SNP_ACTION | tempdb.SNP_ACTION |
<%=odiRef.getCatalogName("MASTER-REP", "DEV", "D")%>.SNP_DATA | db_snpm.SNP_DATA |
<%=odiRef.getCatalogName("W")%>.SNP_HOST | tempdb.SNP_HOST |
<%=odiRef.getCatalogName()%>.SNP_LINK | db_snpm.SNP_LINK |
Использование getCatalogName или getSchemaName применимо для тех СУБД, где полный путь к таблицам или другим объектам кодируется только через 2 параметра: наименование БД и объекта.
Обратите также внимание на то, что необходимо выбрать физическую схему по-умолчанию при наличии нескольких физических схем для одного дата сервера для корректной работы некоторых стандартных модулей знаний и метода getObjectName с параметром pMode = "R"
Использую OdiFileWait дожидаюсь файла, передаю его на дальнейшую обработку. Как можно на самом первом этапе записать реальное имя файла в переменную?
ОтветитьУдалитьЕсть несколько вариантов, включая написание кода на Джава, но простых путей не очень много.
ОтветитьУдалитьВ зависимости от используемой ОС, опробован такой подход.
1. Процедура удаляет временный файл на диске
2. Процедура создает отдельный файл при помощи утилит командной строки ОС, который содержит только список файлов из заданной директории.
3. Интерфейс загружает данные из текстового файла (из пункта 2) в таблицу.
4. По таблице делается рефреш переменной с выбором первого необработанного имени файла.
5. Передается на обработку, где статус файла из таблицы (п. 4) обновляется на обработан.
6. Переход на п. 4.
А как в ODI считать в переменную весь текстовый файл?
ОтветитьУдалитьВот так вот сходу - думаю, что никак.
ОтветитьУдалитьИдеология ELT инструмента, которым является ODI предусматривает что непосредственно работу по преобразованиям выполняет движок БД.
Так что варианты все же есть - только их применимость вызывает сомнения. Например, можно загрузить файл в таблицу, а уже оттуда прочитать в переменную.
Другой вариант - в процедуре создать шаг с джавой и уже при помощи подпрограммы на этом языке загрузить в память файл и что-то сделать с ним.
Вот, тут есть начало обработки файлов в папке
ОтветитьУдалитьhttp://odiexperts.com/getting-one-or-several-unknown-files-from-a-directory/
Спасибо, что отвечаете. Не знаю в какой теме лучше написать, поэтому рискну продолжить тут, хотя это и не относится к данной теме. Есть ли в 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.
Я, к сожалению, не смог сейчас найти быстро пример, но в теории, это должно выглядеть как набор таблиц - datastore, которые преобразовываются при помощи интерфейсов.
ОтветитьУдалитьODI имеет механизм загрузки xml файлов, при котором XSD отображается на логическую схему, конкретный файл на физическую схему ну и контекст переключает использование девелоперского файла на тестовый или файл продакшина.
При этом также есть возможность использования встроенного SQL движка.
Вот тут подробнее
http://sonra.io/under-the-hood-of-the-sunopsis-memory-engine-part-1/