Sql 按排序排序与SSIS(集成服务)中的排序转换不同

Sql 按排序排序与SSIS(集成服务)中的排序转换不同,sql,sorting,ssis,Sql,Sorting,Ssis,使用SSI时,由于使用两个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中选择OLE数据源 按JoinKey a

使用SSI时,由于使用两个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中选择OLE数据源
  • 按JoinKey asc排序表1上的转换,然后按ExpectedValue asc排序
  • OLE数据源按JoinKey asc从表2中选择顺序
  • 使用JoinKey上的表1和表2合并联接转换(左外部联接),选择OriginalValue和ExpectedValue
  • 在这样做的过程中,对于我的一些数据集,ExpectedValue的结果是空值。直接在SQL中执行查询将返回所需的值

    如果我在步骤5之前添加排序转换,它将正确加入ExpectedValue,但是SSIS会发出警告“Validation warning.数据已按指定进行排序,因此可以删除该转换。”

    两个问题:

  • 使用orderby和sort转换不应该产生相同的结果吗
  • 为什么SSI在实际需要排序时会显示警告
  • 我浏览了一些相关的帖子,但它们似乎关注的是效率,而不是功能上的差异


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

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

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


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

    找到一篇Microsoft帖子,指出原因。标记Tab Alleman的回答作为答案,因为这正是导致我发现这一点的原因

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

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


    对服务器1(表1的源代码)和服务器2(表2的源代码)运行这两个查询
    从sys.databases中选择D.name,D.collation_name作为D,其中D.name位于('tempdb','MyDatabase')
    从sys.schemas中选择C.name、C.collation\u name作为S内部连接sys.tables作为T.schema\u id=S.schema\u id内部连接sys.columns作为C.object\u id=T.object\u id,其中S.name=N'MySchema'和T.name='MyTable'和C.name=N'JoinKey'所有结果都是SQL\u拉丁语\u通用\u CP1\u CI\u,这不好。现在我必须考虑另一种情况。(未来的读者,我的假设是,我们有一个Db区分大小写,而不是另一个Db,或者有一个字符集——之前被这两个Db都咬过)我要加入的实际值是字符串A-我最初认为是-是问题所在,但是其他符号,如/和*似乎与上述场景配合良好。快速检查以确保匹配您认为匹配的内容是为文本计算哈希
    CONVERT(varchar(34)、CONVERT(varbinary(20)、HASHBYTES('MD5',T.JoinKey))、1)作为JoinKeyHashBytesASCII
    将该列添加到两个源中,然后使用数据查看器查看计算出的哈希是什么。应该是0xF0412E3C4F9232CFC644F498344EE0749,但如果您得到其他内容,则数据可能存在空白问题。