【问题标题】:Order By sorts differently than Sort Transformation in SSIS (Integration services)排序方式不同于 SSIS 中的排序转换(集成服务)
【发布时间】:2015-05-24 00:03:18
【问题描述】:

由于使用两个 OLE DB 源进行排序,我在加入时遇到了问题。

我发现,如果我使用 order by 与 sort 转换,它会产生不同的结果,从而导致合并连接以生成不正确的数据

例子:

表1

Id int PK
JoinKey varchar(25)
OriginalValue varchar(25)

表2

Id int PK
JoinKey varchar(25)
ExpectedValue varchar(25)

SSIS中的程序流程如下:

  1. 从 Table1 中选择的 OLE 数据源
  2. 通过 JoinKey asc 然后 ExpectedValue asc 对 Table1 进行排序转换
  3. 从 Table2 Order By JoinKey asc 中选择的 OLE 数据源
  4. 在选择 OriginalValue 和 ExpectedValue 的 JoinKey 上使用 Table1 和 Table2 合并连接转换(左外连接)

这样做 - 对于我的一些数据集,我最终得到了 ExpectedValue 的空值。直接在 SQL 中进行查询会返回预期的值。

如果我在第 5 步之前添加排序转换,它会正确加入 ExpectedValue,但是 SSIS 会出现警告“验证警告。数据已按指定排序,因此可以删除转换。”

两个问题:

  1. 不应该使用 order by 和 sort 转换产生相同的结果吗?
  2. 为什么 SSIS 在实际需要排序时会显示警告?

我浏览了一些相关的帖子,但它们似乎关注的是效率而不是功能上的差异。

  1. Is it better to sort data at the application layer, or with an order by clause?
  2. why we need to use sort transformation before merge join transformation in ssis
  3. SQL Server Integration Service Left Join

【问题讨论】:

  • 对服务器 1(表 1 的源)和服务器 2(表 2 的源)SELECT D.name, D.collation_name FROM sys.databases AS D WHERE d.name IN ('tempdb', 'MyDatabase');SELECT C.name, C.collation_name FROM sys.schemas AS S INNER JOIN sys.tables AS T ON T.schema_id = S.schema_id INNER JOIN sys.columns AS C ON C.object_id = T.object_id WHERE S.name = N'MySchema' AND T.name = 'MyTable' AND C.name = N'JoinKey'; 运行这两个查询
  • 所有结果都是SQL_Latin1_General_CP1_CI_AS
  • 那不好。现在我不得不考虑另一种情况。 (未来的读者,我的假设是我们的一个 Db 区分大小写而不是另一个,或者有一个字符集 - 之前都被这两个咬过)
  • 我加入的实际值是字符串 A- 我最初认为 - 是问题,但其他符号(例如 / 和 *)似乎适用于上述情况
  • 快速检查以确保您匹配您认为匹配的内容是计算文本的哈希值。 CONVERT(varchar(34), CONVERT(varbinary(20), HASHBYTES('MD5', T.JoinKey)), 1) AS JoinKeyHashBytesASCII 将该列添加到两个源,然后使用数据查看器查看计算的哈希值是什么。应该是 0xF0412E3C4F9232CFC64F498344EE0749 但如果你得到别的东西,那么你可能有数据的空白问题。

标签: sql sorting ssis


【解决方案1】:

我过去曾遇到过这种情况,答案是否定的,在源 SQL 中使用 ORDER BY 进行排序并不总是与在数据流任务中使用排序转换产生相同的结果。某些特殊(非字母数字)字符(可能还有 NULLS)的处理方式有所不同;我不记得具体是哪个。我不记得找到任何有关此的文档(那是几年前的事了),但我通过自己的测试确认了这一点。

我的结论是,要在数据流中进行 JOIN,请确保在 JOIN 的两侧使用相同的排序方法。

至于您的第二个问题,SSIS 在数据源上有一个 IsSorted 属性。如果您将 DataSource 上的 IsSorted 属性设置为 true,那么如果您尝试进行排序转换,它所知道的只是 IsSorted 为 true,并且会发出不需要排序的警告。它不知道“需要”排序转换以匹配另一个使用排序转换的源。

如果您想在 JOIN 的两侧使用排序转换,请将源的 IsSorted 属性设置为 false。

【讨论】:

    【解决方案2】:

    找到说明原因的 Microsoft 帖子。将 Tab Alleman 的回答标记为答案,因为它是导致我发现这一点的原因。

    排序转换使用 Windows 排序规则对字符串值进行排序。

    您不能单独使用 ORDER BY 子句,因为 ORDER BY 子句使用 SQL Server 排序规则对字符串值进行排序。使用 SQL Server 排序规则可能会导致与 Windows 排序规则不同的排序顺序,这可能会导致合并或合并连接转换产生意外结果。

    https://msdn.microsoft.com/en-us/library/ms137653.aspx

    【讨论】:

      猜你喜欢
      • 2018-05-06
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 2015-08-12
      • 1970-01-01
      • 2012-10-22
      相关资源
      最近更新 更多