SSIS 读取 My Sql 生成的 csv,代码页冲突

SSIS reading csv produced by My Sql, code page conflict

我收到了一个第 3 方文件 - utf-8 编码,56 列,从 MySql 导出的 csv。我的目的是将它加载到 Sql Server 2019 实例中 - 我无法控制的 table 布局。

Sql 服务器导入向导会自动将代码页转换为 latin 1(以及一些字符串到整数的转换),但它不会处理 MySql "\N"无效约定,所以我想我会尝试使用 SSIS 看看是否可以在摄取时清理数据。

我设置了一些组件来进行各种过滤和转换(比如“\N”的东西)并且一切正常。然后我尝试使用 OLE DB 目标 保存 数据,结果车轮有点掉下来了。

SSIS 似乎放弃了导入向导会执行的所有自动转换并强制您进行显式转换。

我将数据转换组件添加到流程中并编辑所有 56 列以明确各种转换 - 只有它让我编辑输出列代码页的“副本”它不会保存他们。在编辑器或高级编辑器中。

我在这里看到另一篇文章说“使用派生列转换”,但这似乎是逐列的(所以我必须添加其中的 56 个)。

SSIS 在这方面比导入向导、bcp 或 BULK INSERT 倒退了一大步,这似乎有点疯狂。

有没有办法使用 SSIS 组件让它通过 SSIS 中的代码页切换工作?我看到推荐的所有组件似乎都不起作用,所有其他文章都说“使用不同的代码页或 NVARCHAR 制作另一个 table,然后将一个 table 复制到另一个”有点违背目的。

综合了许多关于切线相关问题的不同帖子,但我想我终于让 SSIS 做了很多导入向导和 BULK INSERT 免费提供的功能。

似乎要使用 SSIS 读取 utf-8 csv 文件并将其一直处理到 1252 中的 table 并且不使用 NVARCHAR 涉及以下内容:

  1. 创建平面文件源组件并将传入编码设置为 65001 (utf-8)。在高级编辑器中,将所有字符串列从 DT_STR/65001 转换为 DT_WSTR(本质上是 NVARCHAR)。在工作流程的其余部分使用这些输出会更容易,而且(最重要的是)数据转换转换组件不会让您从 65001 转换为任何其他代码页。但它 让您在不同的代码页中从 DT_WSTR 转换为 DT_STR。

1a) SSIS 在默认情况下将默认的 50 长度设置为非常烦人。并且不将任何长度作为默认值从一个 component/transform 传递到下一个。因此,您必须仔细检查平面文件源 您在该组件中创建的所有 WSTR 转换的所有“第 0 列”输入列并设置适当的长度。

1b) 如果您的输入文件偶尔包含无效的 utf-8 编码,就像我的一样,请选择“RD_RedirectRow”作为每一列的截断错误处理。然后将平面文件目标添加到您的工作流中,并将来自平面文件源的红线附加到它。那就是如果你想看看哪一行是坏的。如果您不关心输入错误,您可以只选择“RD_IgnoreError”。但是保留默认值意味着如果遇到任何错误数据,您的整个包都会爆炸

  1. 创建脚本转换组件,在该脚本中您可以检查每一列的 MySql“\N”并将其更改为 null。

  2. 创建一个数据转换转换组件并将其添加到您的工作流中。由于步骤 1 中的 DT_WSTR,您现在可以在此处的不同代码页中将该输出更改回 DT_STR。如果您不从一开始就更改为 DT_WSTR,则数据转换组件将无法在这一步更改代码页。我得到的 99% 的数据只有拉丁字符,utf-8 编码(重音符号)。在一小部分数据中有一些汉字字符,因此要重现导入向导为您所做的事情,您必须将此处可能受影响的每一列的截断错误处理更改为 RD_IgnoreError。与我读过的一些文档不同,RD_IgnoreError 不会将 null 放入列中;它将带有非映射字符的文本替换为“?”就像我们都习惯了。

  3. 添加 OLE DB 目标组件并将步骤 3 中的所有输出列映射到数据库的列。

因此,返回导入向导并开始获取 SSIS 可以为您做的额外事情的大量工作已经开始。当您更改某些内容时,SSIS 会将列宽重新设置为默认的 50,这可能有点烦人。如果您有很多专栏,这会变得非常乏味。