有没有办法将 SSIS Merge Join 与 SQLServer OLEDB 源和 MySQL/ODBC 源一起使用

Is there a way to use an SSIS Merge Join with a SQLServer OLEDB source and MySQL/ODBC source

我正在使用 SQL Server 2012,需要使用 Merge Join 进行完整的外部联接才能进行增量 updates/inserts/deletes。

我们真的很想避免使用排序转换,因为它是完全阻塞的,但我 运行 没有主意。

两个源输出都使用 order by 子句进行排序,并且 IsSorted 属性 设置为 true/columnSort 顺序设置为 1。

MySQL 数据库的字符集是 UTF8 在源查询的 order by 子句中,我使用 UTF8_bin

进行整理

SQL服务器数据库的排序规则是SQL_Latin1_General_CP1_CI_AS但是在源查询中的order by子句中我已经排序为Latin1_General_bin(所以排序方法是一样的)

但是我发现集合没有正确连接。大多数记录确实匹配,但我有一些情况,其中值存在于左侧和右侧,但连接的另一侧为空(理论上它们应该匹配)

我们尝试匹配的值采用以下格式 (99999-99999-9999 AAA BBB CCC)

我知道 SQL 服务器中的 UTF8 支持直到 SQL Server 2019 才引入,所以这可能是问题所在。我们是否不可避免地要使用排序转换?

如果您信任来自这两个来源的排序,您只需在“高级编辑”部分中为数据源的输出设置 "Is Sorted" 属性。然后为应用排序的任何列设置一个位置。如果只有一列进行排序,只需在该列上输入 1。

但要小心,因为如果顺序不同,它会呕吐。如果它是一个数字,你可能没问题,或者你提到的那种格式也可能没问题。但一般来说,我不相信字符串。

在对字符编码进行一些研究后,我设法解决了这个问题。

MySQL UTF8 更集中于 linux 和 UNIX,Windows UTF8 支持非常有限,因此 UTF8 归类可能会导致问题。

但是 Windows 确实支持 UTF16...不过它仍然不是直截了当的。

在MySQL中有字符集UTF16和UTF16LE。 LE 代表小端。 UTF16 使用 big endian,简而言之,它将按序列中的最高有效值排序,而不是 little endian,它按序列中的最低有效值排序。欲了解更多信息,请阅读以下内容。

[https://searchnetworking.techtarget.com/definition/big-endian-and-little-endian][1]

Windows服务器使用的编码将主要使用little endian,因为如上文所述,它由服务器的CPU决定(例如Intel处理器使用little endian)。

考虑到这一点,我将 SQL 服务器源中的 Join/Sort 列 (nvarchar(55)) 整理为 Latin1_General_Bin,理论上应该是 UTF16 little endian 编码。

然后我将 MySQL 源中的 Join/Sort 列转换为 UTF16LE 字符集,并将整理顺序中的 Join/Sort 列转换为 UTF16LE_Bin

SELECT
CONVERT(UPPER(CONCAT_WS('-', Column1, Column2, Column3, 'AAA BBB CCC')) USING UTF16LE) AS DerivedColumn,
...
...
ORDER BY DerivedColumn COLLATE UTF16LE_bin;

这无需使用排序转换即可正确排序数据。