排序方式不同于 SSIS 中的排序转换(集成服务)
Order By sorts differently than Sort Transformation in SSIS (Integration services)
使用 SSIS 由于使用两个 OLE DB 源进行排序,我在加入时遇到了问题。
我发现,如果我使用 order by 与排序转换,它会产生不同的结果,导致合并连接生成不正确的数据
示例:
表 1
Id int PK
JoinKey varchar(25)
OriginalValue varchar(25)
表 2
Id int PK
JoinKey varchar(25)
ExpectedValue varchar(25)
SSIS中的程序流程如下:
- 从表 1 中选择的 OLE 数据源
- 按 JoinKey asc 然后 ExpectedValue asc 对 Table1 进行排序转换
- OLE 数据源从 Table2 中选择 Order By JoinKey asc
- 在 JoinKey 上选择 OriginalValue 和 ExpectedValue 与 Table1 和 Table2 合并连接转换(左外连接)
在这样做时 - 对于我的某些数据集,我最终得到了 ExpectedValue 的空值。直接在 SQL returns 预期值中进行查询。
如果我在第 5 步之前添加排序转换,它会正确加入 ExpectedValue 但是 SSIS 会收到警告 "Validation warning. The data is already sorted as specified so the transform can be removed."
两个问题:
- 使用 order by 和 sort 转换不应该产生相同的结果吗?
- 为什么在实际需要排序时 SSIS 会发出警告?
我浏览了一些相关的帖子,但他们似乎关注效率而不是功能差异。
- Is it better to sort data at the application layer, or with an order by clause?
- SQL Server Integration Service Left Join
我过去曾遇到过这种情况,答案是否定的,在源 SQL 中使用 ORDER BY 排序并不总是产生与在数据流任务中使用排序转换相同的结果。某些特殊(非字母数字)字符(可能还有 NULLS)的处理方式有所不同;我记不清是哪一个了。我不记得找到任何关于此的文档(那是几年前的事了),但我通过自己的测试证实了这一点。
我的结论是,要在数据流中进行 JOIN,请确保在 JOIN 的两侧使用相同的排序方法。
关于你的第二个问题,SSIS 在数据源上有一个 IsSorted 属性。如果您将 DataSource 上的 IsSorted 属性 设置为 true,那么如果您尝试进行排序转换,它所知道的就是 IsSorted 是 true 并且它会发出不需要排序的警告。它不知道排序转换是 "needed" 以匹配另一个使用排序转换的源。
如果您想在 JOIN 的两边都使用排序转换,请将源的 IsSorted 属性 设置为 false。
找到微软post说明原因。将 Tab Alleman 的回应标记为答案,因为正是它让我找到了这个答案。
排序转换使用 Windows 排序规则对字符串值进行排序。
您不能单独使用 ORDER BY 子句,因为 ORDER BY 子句使用 SQL 服务器排序规则对字符串值进行排序。使用 SQL 服务器排序规则可能会导致与 Windows 排序规则不同的排序顺序,这会导致合并或合并联接转换产生意外结果。
使用 SSIS 由于使用两个 OLE DB 源进行排序,我在加入时遇到了问题。
我发现,如果我使用 order by 与排序转换,它会产生不同的结果,导致合并连接生成不正确的数据
示例:
表 1
Id int PK
JoinKey varchar(25)
OriginalValue varchar(25)
表 2
Id int PK
JoinKey varchar(25)
ExpectedValue varchar(25)
SSIS中的程序流程如下:
- 从表 1 中选择的 OLE 数据源
- 按 JoinKey asc 然后 ExpectedValue asc 对 Table1 进行排序转换
- OLE 数据源从 Table2 中选择 Order By JoinKey asc
- 在 JoinKey 上选择 OriginalValue 和 ExpectedValue 与 Table1 和 Table2 合并连接转换(左外连接)
在这样做时 - 对于我的某些数据集,我最终得到了 ExpectedValue 的空值。直接在 SQL returns 预期值中进行查询。
如果我在第 5 步之前添加排序转换,它会正确加入 ExpectedValue 但是 SSIS 会收到警告 "Validation warning. The data is already sorted as specified so the transform can be removed."
两个问题:
- 使用 order by 和 sort 转换不应该产生相同的结果吗?
- 为什么在实际需要排序时 SSIS 会发出警告?
我浏览了一些相关的帖子,但他们似乎关注效率而不是功能差异。
- Is it better to sort data at the application layer, or with an order by clause?
- SQL Server Integration Service Left Join
我过去曾遇到过这种情况,答案是否定的,在源 SQL 中使用 ORDER BY 排序并不总是产生与在数据流任务中使用排序转换相同的结果。某些特殊(非字母数字)字符(可能还有 NULLS)的处理方式有所不同;我记不清是哪一个了。我不记得找到任何关于此的文档(那是几年前的事了),但我通过自己的测试证实了这一点。
我的结论是,要在数据流中进行 JOIN,请确保在 JOIN 的两侧使用相同的排序方法。
关于你的第二个问题,SSIS 在数据源上有一个 IsSorted 属性。如果您将 DataSource 上的 IsSorted 属性 设置为 true,那么如果您尝试进行排序转换,它所知道的就是 IsSorted 是 true 并且它会发出不需要排序的警告。它不知道排序转换是 "needed" 以匹配另一个使用排序转换的源。
如果您想在 JOIN 的两边都使用排序转换,请将源的 IsSorted 属性 设置为 false。
找到微软post说明原因。将 Tab Alleman 的回应标记为答案,因为正是它让我找到了这个答案。
排序转换使用 Windows 排序规则对字符串值进行排序。
您不能单独使用 ORDER BY 子句,因为 ORDER BY 子句使用 SQL 服务器排序规则对字符串值进行排序。使用 SQL 服务器排序规则可能会导致与 Windows 排序规则不同的排序顺序,这会导致合并或合并联接转换产生意外结果。