【问题标题】:Flat File to SQL Server (BULK INSERT) ODI 11g Knowledge Module Only Loading Half of Records from Flat File平面文件到 SQL Server (BULK INSERT) ODI 11g 知识模块仅从平面文件加载一半记录
【发布时间】:2019-11-27 20:47:43
【问题描述】:

我正在使用 Oracle Data Integrator 11g 接口将包含超过一百万条记录的平面文件连接到 SQL Server 表。鉴于使用通用知识模块的一些性能问题 - 我正在利用平面文件到 SQL Server(批量插入)LKM 的使用,这极大地提高了接口性能,因为 ODI 代理使用 SQL Server 上的本机 BCP 实用程序批量加载记录.

知识模块为 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. 第二个问题是通过 ODI LKM 的 BCP 实用程序似乎“非常强大”,因为它忽略了我在 ODI 平面文件模型中定义的字段分隔符,并解析出包含多个管道的字段”。在不使用 BCP 的普通知识模块中,被“”包围并包含多个管道的字段不被分隔为单独的组件。我注意到,即使 ODI 平面文件模型指定字段分隔符“”——创建的批量插入 sql 查询也不包括在 SQL 代码中。就好像批量插入忽略了这个字段分隔符(它似乎识别了 | 字段分隔符)

我的印象是,我将不得不编写自己的自定义 BULK INSERT sql 语句——我完全可以接受——以确保上述两个问题都得到纠正。我正在寻找是否有人对可以解决这两个问题的批量插入查询有任何见解。

我尝试更改平面文件的分隔符和编码 - 无济于事。有一些文献可以格式化文件 - 但我需要 ODI 逐步执行此操作,因为即使我们不使用 LKM,这仍将是自动化的。

我的想法是我需要

  1. 我将插入到 ODI 中以执行或执行的自定义批量插入脚本

  2. 我需要创建一个自定义知识模块。

我更喜欢做 1. 但需要构建脚本。

这就是 ODI 通过与 Flat File 到 SQL Server(批量)LKM 对应的声明性设计执行的操作。

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,因为文件中的标题。

【问题讨论】:

    标签: sql-server bulkinsert bcp data-integration oracle-data-integrator


    【解决方案1】:

    您需要在批量插入语句中使用格式文件。这是必需的,因为 SQL BCP 不允许考虑数据中包含的引号来隐藏/屏蔽数据中显示的给定字段终止符。此外,您将需要自定义(单个)字段终止符(并非所有字段都将以相同的值终止...例如您当前使用的“|”)。

    使用 BCP 格式文件,您可以为传入文件指定自定义字段终止符。每个字段都在格式文件中被调用,因此每个字段都定义了自己的终止符。例如,您的第三个字段将由“|\”而不是“|”终止(“\”将转义您包含在数据中的双引号,因此它不会被视为包含您的字段的真正 dbl-quote格式文件中的终止符)。

    同时,您的第 4 列将不再以“|”结尾但现在将由 "\"\r\n" 终止(假设您使用的是标准 crlf 终止符)。同样,这里的第一个和最后一个双引号是 bcp 将从格式文件中读取的实际 dbl 引号包含分隔符(现在是“行”分隔符,因为我们在最后一个字段)。您必须使用“\”字符转义内部的 dbl-quote。\r\n 是 crlf 的标准 bcp 表示。

    【讨论】:

    • 嗨,杰米 - 感谢您提供的信息!抱歉耽搁了-我建立了一个可以很好地使用它的格式文件!我的领导想知道您是否必须为所有内容指定终止符 - 我的猜测是肯定的。
    • 是的,在格式文件中,每个字段都会有一个终止符。最后一个字段将有一个行终止符。因此对于 csv 文件,所有字段都将具有“,”作为分隔符。最后一个字段将有“\r\n”之类的内容,或者只是“\n”,具体取决于您想要的内容。
    • 谢谢 Jamie - 只是想知道您是否确切知道为什么没有格式文件 BCP 实用程序只能加载一半的记录? BCP 似乎理解了一半的记录是否有一个具体的细微原因 - 通常记录的顺序似乎与平面文件中记录的顺序不匹配。加载了随机记录 - 甚至一些带有分隔符。或者这只是一种 BCP 行为,真的需要对工具有超深的了解。
    • 文件有多大?字节数。
    • 595,000 KB
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2019-07-19
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多