我有从源读取的SSIS包,执行查找转换,以检查记录是否在目标中,如果存在,则将其重定向以匹配输出并更新它,否则将其不匹配并插入。问题在于有时它会插入一条记录,该记录应重定向以进行更新。这是通过作业完成的,如果我手动执行程序包,一切都很好。使用匹配列正确设置了查找组件。
我不知道为什么会这样,最愚蠢的是我无法调试它,因为手动一切都很好。
有什么想法吗?
答案 0 :(得分:2)
在有插入内容应该是更新的情况下,有两个选项。
首先,您的源数据中有重复的键,而目标表中没有任何键。
Key|Value
A |abc
B |bcd
A |cde
Key|Value
C |yza
B |zab
在这种情况下,假设在包开始执行之前Lookup组件具有默认行为,即完全缓存,SSIS将运行Lookup参考表的源查询。只有所有的查询表数据都已被缓存后,数据流才会成为流动数据。
当程序包启动时,它只知道目标表中的数据。在运行期间,您向表中添加了相同的键值,但从未要求查询组件检查更新。
在这种情况下,有两种解决方法:第一种是将缓存模式从“完全”更改为“无”(或“部分”)。这将使查找组件针对流过数据流的每行的目标表发出查询。对于大行而言,这可能会变得昂贵。它也不是万无一失的,因为数据流具有缓冲区的概念,并且在示例3行加载的情况下,它们都适合放在一个缓冲区中。缓冲区中的所有行将在大约同一时间命中“查找”,因此,当第三行流经组件时,目标表仍将不包含A值。您可以通过将缓冲区大小调整为1来阻止数据流并强制其一次处理一行,但这通常不是一个好的解决方案。
另一个解决方案是重复数据删除/处理生存。如果我们的源对于同一业务密钥具有不同的值,则应该将其放入数据库的哪一行?首先,最后选择一个?如果您无法在数据到达“数据流”之前消除数据,那么您将需要使用“聚合”组件对数据进行重复数据删除,以最大程度地汇总数据。
Key|Value
A |abc
B |bcd
a |cde
Key|Value
C |yza
B |zab
查找组件咬住您的另一种情况是,默认的完全缓存匹配基于字符串的.NET匹配规则。因此,AAA不等于AaA。如果您的查询正在进行字符串匹配,即使您的数据库不区分大小写 ,SSIS查询也不会不敏感。
在需要匹配Alpha数据的情况下,通常会在源数据中添加一个多余的/重复的列,这是全部为大写或小写形式的关键数据。如果查询数据,则将其添加到查询中。如果要从平面文件加载,则可以使用派生列组件将列添加到数据流中。
然后,当我使用Lookup组件时,确保引用表中的数据大小写相同。
全缓存模式: -对参考数据的更改不敏感 -区分大小写的匹配 -总的来说更快 -延迟数据流,直到缓存了查询数据为止 -NULL匹配空字符串 -缓存的数据需要RAM
无缓存模式: -对参考的变化敏感 -区分大小写匹配基于查找系统的规则(DB区分大小写,您将获得敏感匹配) -这取决于(100行源数据,1000行参考数据-没有人会注意到。 1B行的源数据和10B行的参考数据-有人会注意到。是否有索引来支持查找等) -NULL不匹配 -没有明显的SSIS内存开销
部分缓存: 部分缓存与“无缓存”选项几乎一样,除了部分缓存与参考表匹配之后,它将缓存该值直到执行结束或由于内存压力而被推出