首页 > 解决方案 > 有没有办法将 SSIS 合并连接与 SQLServer OLEDB 源和 MySQL/ODBC 源一起使用

问题描述

我正在使用 SQL Server 2012,需要使用 Merge Join 进行完整的外部联接,以便进行增量更新/插入/删除。

我们真的很想避免使用排序转换,因为它是完全阻塞的,但我已经没有想法了。

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

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

SQLServer 数据库的排序规则是 SQL_Latin1_General_CP1_CI_AS 但在源查询中的 order by 子句中,我已经对 Latin1_General_bin 进行了排序(所以排序方法是相同的)

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

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

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

标签: mysqlsql-serversortingcollationssis-2012

解决方案


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

MySQL UTF8 更多地以 linux 和 UNIX 为中心,Windows UTF8 支持非常有限,因此 UTF8 排序规则可能会导致问题。

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

在 MySQL 中有字符集 UTF16 和 UTF16LE。LE 代表小端。UTF16 使用大端序,简而言之,它将按序列中最重要的值排序,而不是小端序,它按序列中最不重要的值排序。有关更多信息,请阅读以下内容。

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

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

考虑到这一点,我将 SQL Server Source 中的 Join/Sort 列 (nvarchar(55)) 整理到 Latin1_General_Bin,理论上应该是 UTF16 little endian Encoding。

然后我将 MySQL 源中的 Join/Sort Columns 转换为 UTF16LE 字符集,并将 Order By Collat​​ed 转换为 UTF16LE_Bin

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

这对数据进行了正确排序,无需使用排序转换。


推荐阅读