C# SSIS-将重复列设置为null

C# SSIS-将重复列设置为null,c#,sql-server,ssis,duplicates,C#,Sql Server,Ssis,Duplicates,我有一个平面文件中的数据(客户端发送给我,无法编辑),其中有一些重复的电子邮件地址,我想设置为null。我们的软件需要一个唯一的电子邮件地址,所以当它遇到一个重复的,它会失败。我们的开发人员正在努力纠正这一点,但与此同时,我想将重复的电子邮件设置为空。以下是一个例子: Client ID | Client Name | Email address 1234 | Mike Smith | MikeSmith@MikesMotors.com 5678 |

我有一个平面文件中的数据(客户端发送给我,无法编辑),其中有一些重复的电子邮件地址,我想设置为null。我们的软件需要一个唯一的电子邮件地址,所以当它遇到一个重复的,它会失败。我们的开发人员正在努力纠正这一点,但与此同时,我想将重复的电子邮件设置为空。以下是一个例子:

Client ID |  Client Name    | Email address
 1234     |   Mike Smith    |  MikeSmith@MikesMotors.com
 5678     |   Mike's Motors |  MikeSmith@MikesMotors.com

因此,在上面的示例中,我希望两行都进入数据库,但我希望将其中一行的电子邮件地址设置为null,但不是两行都设置为null。

您可以使用row_number函数找出重复项并将其设为null

这里有一种方法

;

WITH mycte
AS (
    SELECT 1234 ClientID
        ,'Mike Smith' ClientName
        ,'MikeSmith@MikesMotors.com' Emailaddress
    
    UNION ALL
    
    SELECT 5678
        ,'Mikes Motors'
        ,'MikeSmith@MikesMotors.com'
    )
SELECT ClientID
    ,ClientName
    ,CASE 
        WHEN ROW_NUMBER() OVER (PARTITION BY Emailaddress ORDER BY Emailaddress) > 1
            THEN NULL
        ELSE Emailaddress
        END AS Emailaddress
FROM mycte

SSIS数据流中没有本机组件可以完成此任务。问题在于,数据流引擎是一个速度惊人的数据处理器,但它通常只知道这一行。不是它前面的那一行,也不是它后面的那一行——只是当前的那一行(而且它有许多同时运行的仆从,他们只知道自己的那一行)

聚合运算符和缓存查找可能会被黑客攻击,但您必须加倍处理该文件。启动数据流将是源->聚合组件->缓存目标。您可以按电子邮件地址分组,然后在聚合组件中最小化或最大化客户端id。当我输入时,我大脑中一个很小的部分说聚合字段和字符串字段有一个愚蠢的限制。也许这只是因为您不能最小化/最大化它们,但允许分组。我假设ClientID和电子邮件地址是唯一的。如果clientid123同时拥有两个mike。smith@mail.com还有迈克。smith@gmail.com,这种方法会起作用,但您需要一种更好的机制来确定数据存活率

因此,启动数据流将运行,并且您有一个缓存,其中填充了唯一的电子邮件地址和您希望保留电子邮件地址的客户端ID

在现有的数据流中,我们将忽略来自源的电子邮件地址。您可以取消它的映射,这样它就不会进入行缓冲区,或者记住我们希望从查找中获得电子邮件地址。在源和目标之间添加查找转换。使用缓存连接管理器对其进行配置,并使用我们在启动步骤中刚刚创建/填充的CCM。指出在不匹配的情况下,忽略故障。将数据流缓冲区中的客户端ID映射到CCM中的客户端ID列。检查来自CCM的电子邮件地址,使其在数据流缓冲区中可用。假设我们称之为EmailAddress\u LKP

在目的地中,将EmailAddress列映射到从查找中生成的值EmailAddress\u LKP


另一种方法是编写一个异步脚本组件(异步是唯一可以访问超过当前缓冲区的方法,但要以内存和速度为代价)。在那里,您可能会构建一个看到的电子邮件地址的映射,如果有匹配项,请指定输出缓冲区列的IsNull属性为true,因此,我找到了一个“低技术”解决方案。我使用了多播,然后是排序。然后,我按电子邮件字段排序,并将其设置为删除重复记录。我取消选中了排序的passthrough中的所有列,除了email字段和join键。然后,我使用左联接将其重新联接到数据流中,除联接左侧的电子邮件字段外,其余字段均为左联接,只有右侧的电子邮件字段为左联接。

这假设数据已加载到暂存table@KeithLSSI已标记。没有理由不能这样做!即使没有SSI,您也可以在一个查询中执行此操作,而无需任何临时表来确认,多封电子邮件是不好的,多个空值是可以的?