Плоский файл в SQL Server (BULK INSERT) ODI 11g Knowledge Module загружает только половину записей из плоского файла

Я использую интерфейс Oracle Data Integrator 11g для сопряжения плоского файла, содержащего более миллиона записей, с таблицей SQL Server. Учитывая некоторые проблемы с производительностью при использовании модулей общих знаний - я использую использование плоского файла для SQL Server (массовая вставка) LKM, что значительно повышает производительность интерфейса, поскольку агент ODI использует встроенную служебную программу BCP на SQL Server для массовой загрузки записей. .

Модуль знаний создает очень простой запрос массовой вставки для агента ODI, чтобы затем выполнить служебную программу BCP. Плоский файл, который у меня есть, взят из Oracle PBCS - мы используем ODI 11g для сопоставления через интерфейс. Из-за формата плоского файла мы используем в модели плоского файла ODI текстовый разделитель | (вертикальная черта) и разделитель полей, чтобы гарантировать, что поле, содержащее несколько конвейеров, которые окружены, становится одним элементом данных, а не разбивается разделителем на подкомпоненты.

Так, например, запись, которая выглядит как

FY19|ContractX|FundX|"BOCX|ProgramX|VersionX|ScenarioX"

это будет отображаться в таблице SQL Server как (столбцы, разделенные пробелом).

FY19 ContractX FundX BOCX|ProgramX|VersionX|ScenarioX 

вместо

FY 19 ContractX FundX BOCX ProgramX VersionX ScenarioX

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

Все остальные поля, разделенные вертикальной чертой, которых нет, рассматриваются как элементы с разделителями. В общем случае (простой файл для SQL Server, не использующий утилиту SQL Server bcp, а, скорее, родную технологию интерфейса ODI) это работает как шарм, чтобы гарантировать, что это происходит, как описано выше.

Однако, когда мы выполняем интерфейс, массовая вставка делает две странные вещи.

  1. Утилита BCP загружает только половину записей плоского файла. Кодировка плоских файлов - UTF-8, разделенная вертикальной чертой. Я кое-что прочитал по этому поводу (все столбцы и значения столбцов совпадают, поэтому сам файл в порядке) - не уверен, есть ли быстрый простой сценарий, который позволит мне отформатировать файл таким образом, чтобы - после форматирования - массовая вставка SQL Server после этого загрузится правильно. Также не помогает то, что записи, которые успешно загружены в таблицу SQL Server, неупорядочены и случайны (не основаны на порядке в плоском файле даже удаленно).

    Это, очевидно, самая большая проблема - сначала нужно решить эту проблему.

  2. Вторая проблема заключается в том, что утилита BCP через ODI LKM кажется «действительно мощной» в том смысле, что она игнорирует мой разделитель полей «определенный в модели плоского файла ODI» и анализирует поле, содержащее несколько каналов, все в пределах «». В обычном модуле знаний, который не использует BCP - поле, окруженное знаком «» и содержащее несколько каналов, не разделено на отдельные компоненты. Я заметил, что даже когда модель плоских файлов ODI определяет разделитель полей «- созданный sql-запрос массовой вставки не включает это в код SQL. Это похоже на то, как если бы объемная вставка игнорировала этот разделитель полей (кажется, что он распознает разделитель полей |)

У меня сложилось впечатление, что мне придется написать свой собственный SQL-оператор BULK INSERT, который меня полностью устраивает, чтобы убедиться, что обе указанные выше проблемы исправлены. Я хочу узнать, есть ли у кого-нибудь представление о запросе массовой вставки, который решит обе проблемы.

Я попытался изменить разделитель и кодировку в плоском файле - безрезультатно. Существует некоторая литература по форматированию файла, но мне понадобится ODI, чтобы выполнить это поэтапно, поскольку это все равно будет автоматизировано, даже если мы не будем использовать LKM.

Я думаю, что мне понадобится

  1. Пользовательский сценарий массовой вставки, который я вставляю в ODI для выполнения или

  2. Мне нужно было бы создать специальный модуль знаний.

Я предпочитаю сделать 1. но мне нужно будет построить сценарий.

Это то, что ODI выполняет с помощью декларативного дизайна, соответствующего LKM от плоского файла к SQL Server (массового).

BULK INSERT BFS_DM.ODI_Work.TC$_0Cld_Ess_SpendPln_Final     
FROM 'E:\EPM_Cloud/Exports/BUD_PLN/Data/Export_SpendPlan_BI_BUD_PLN.txt'     
WITH
    (
     CODEPAGE  = 'ACP' 
     , DATAFILETYPE  = 'char '
     , FIELDTERMINATOR  ='|' 
     , FIRSTROW =2
     , TABLOCK 
    )

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

Кроме того, этот код загружает только половину записей - интересно, как я могу исправить это с помощью дополнительных строк кода в массивной вставке выше.

Firstrow = 2 из-за заголовка файла.


person smomotiu    schedule 18.07.2019    source источник


Ответы (1)


Вам необходимо использовать файл формата с оператором массовой вставки. Это необходимо, потому что SQL BCP не позволяет учитывать кавычки, включенные в данные, чтобы скрыть / замаскировать указанный терминатор поля, отображаемый в ваших данных. Кроме того, вам понадобятся специальные (индивидуальные) терминаторы полей (не все поля будут заканчиваться одним и тем же значением ... например, "|" в вашем текущем использовании).

Используя файл формата BCP, вы можете указать терминаторы настраиваемых полей для входящего файла. Каждое поле вызывается в файле формата, поэтому для каждого поля определен свой собственный терминатор. Например, ваше 3-е поле будет завершено "| \" ", а не" | "(" \ "будет экранировать двойные кавычки, которые вы включили в данные, поэтому оно не будет рассматриваться как истинная dbl-цитата, содержащая ваше поле терминатор в файле формата).

В то же время ваш 4-й столбец больше не будет заканчиваться знаком "|" но теперь будет завершаться "\" \ r \ n "(предполагается, что вы используете стандартный терминатор crlf). Опять же, первая и последняя двойные кавычки здесь являются фактическими кавычками dbl, которые bcp будет читать из файла формата как содержащий разделитель (разделитель "строка" теперь, поскольку мы находимся в последнем поле). Вы должны экранировать dbl-кавычку внутри с помощью символа "\". \ r \ n является стандартным bcp-представителем crlf.

person jamie    schedule 18.07.2019
comment
Привет, Джейми - спасибо за эту информацию! Извините за задержку - я создал файл формата, который хорошо работает с этим! Моя ведущая задается вопросом, нужно ли указывать терминатор для всего - думаю, да. - person smomotiu; 01.08.2019
comment
Да, в файле формата каждое поле будет иметь терминатор. последнее поле будет иметь терминатор строки. поэтому для файла csv все поля будут иметь в качестве разделителя. В последнем поле будет что-то вроде \ r \ n или просто \ n, в зависимости от того, что вы хотите. - person jamie; 01.08.2019
comment
Спасибо, Джейми. Просто интересно, знаете ли вы, почему без файла форматирования утилита BCP загружает только половину записей? Есть ли какая-то конкретная причина, по которой BCP, похоже, понимает половину записей - порядок записей в целом, похоже, не соответствует порядку записей в плоском файле. Загружались случайные записи - даже с разделителями. Или это просто поведение BCP, которое действительно потребует очень глубоких знаний об инструменте. - person smomotiu; 02.08.2019
comment
насколько велик файл? количество байтов. - person jamie; 03.08.2019
comment
595 000 килобайт - person smomotiu; 06.08.2019