2011-08-04 156 views
2

我有一个每晚从SS400数据库系统导出TON数据的SSIS过程。由于AS400 DB软件中存在错误,因此将重复项密钥插入数据表中。每次将新的副本添加到AS400表时,它都会导致我晚上的导出过程中断。这个问题已经从滋扰变成了问题。如何在准特有数据密钥上创建主密钥?

我需要的是有一个选项,只插入唯一的数据。如果有重复,请选择第一个遇到的重复行的行。有没有SQL语法可以帮助我做到这一点?我知道DISTINCT ROW子句,但在我的情况下不起作用,因为对于大多数违规记录,除组成PK的字段外,整个数据是非唯一的。

就我而言,我的主键在我的SQL Server数据库缓存中保持唯一性,而不是拥有数据的完整快照更为重要。有什么我可以做的强制这个约束出口在SSIS/SQL Server与崩溃的过程?

编辑

让我进一步明确了我的要求。我需要的是确保导出的SQL Server表中的数据与维护AS400数据表的数据保持相同的密钥。换句话说,创建唯一的行计数标识符将不起作用,也不会在没有主键的情况下插入所有数据。

如果AS400软件中的错误允许错误的重复PK,我想要忽略这些行,或者最好只选择具有重复键的行中的一个,但不能同时选择这两个行。

该SELECT语句可能发生在我的SSIS项目中的SELECT语句中,该语句通过ODBC连接连接到大型机。

我怀疑我的问题可能没有“简单”解决方案。然而,我希望我错了。

回答

2

由于您使用SSIS,您必须使用OLE DB Source来从AS400中的数据,你会使用OLE DB Destination将数据插入到SQL Server。

让我们假设你没有任何转换

Data Flow Task

添加Sort transformation的OLE DB源之后。在排序转换中,底部有一个复选框选项,可根据给定的一组列值删除重复的行。检查所有字段,但不要选择来自AS400的主键。这将消除重复的行,但会插入仍然需要的数据。

Sort

我希望这是你在找什么。

+0

我应该只检查与PK关联的列吗?当我执行任务时,我仍然受到PK侵犯。 – RLH

+0

另外,假设我确实有转换,我会做什么不同?在我的情况下,我有一个转换,从每个文本字段的末尾截断填充间距。 – RLH

+0

这似乎是正确的答案,但我仍然得到PK Vialation错误。我进行了三重检查 - 我没有选中所有的PK字段(在这种情况下,有8个字段),并且在SORT转换之后放置了我的转换。我可以错过任何东西吗? – RLH

1

SQL Server 2005及以上:

SELECT * 
FROM (
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY almost_unique_field ORDER BY id) rn 
     FROM import_table 
     ) q 
WHERE rn = 1 
+0

我可能需要编辑我的问题,但这不是我的意思。我想说的是,如果一个字段应该是唯一的,但不是,有没有办法获得一些数据?是的,可以添加一个行号。但是我需要的是找到一种方法来锁定我在SQL Server中唯一的独特PK,尽管它们在源数据库中并不是唯一的。 – RLH

+0

@RLH:请发布一些示例输入和输出数据,因为您想查看它。 – Quassnoi

+0

这可以在执行SQl任务的SSIS中使用。我总是将原始数据放入临时表中,然后在设置变换之前执行类似的任务。您也可以将复制的记录移动到异常表中,以便稍后检查不同的数据以查看您导入的数据是否需要更改或用于发送回源以告诉它们他们有数据问题。它还有助于将排除在异常表中的数据存储起来,因为迟早有人会想知道为什么他们看不到他们知道的其他系统中的某些内容。 – HLGEM

1

有几种选择。

如果您在主键上使用IGNORE_DUP_KEY(http://www.sqlservernation.com/home/creating-indexes-with-ignore_dup_key.html)选项,SQL将发出警告并且只有重复记录将失败。

您也可以对数据进行分组/汇总,但这可能会非常昂贵。我的意思是:

SELECT Id, MAX(value1), MAX(value2), MAX(value3) etc 

另一种选择是(在此为一个有效的后加入和簇)添加标识列到你的临时表中,然后创建一个临时表的映射。映射表是:

CREATE TABLE #mapping 
( 
    RowID INT PRIMARY KEY CLUSTERED, 
    PKIN INT 
) 

INSERT INTO #mapping 
SELECT PKID, MIN(rowid) FROM staging_table 
GROUP BY PKID 

INSERT INTO presentation_table 
SELECT S.* 
FROM Staging_table S 
    INNER JOIN #mapping M 
     ON S.RowID = M.RowID 
0

如果我理解正确的话,你有重复的PK有在其他领域不同的数据。

首先,将来自其他数据库的数据放入登台表中。如果我这样做,我发现更容易研究进口(尤其是大型)的问题。实际上我使用两个临时表(对于这种情况我强烈推荐它),一个使用原始数据,另一个仅使用我想要导入到系统中的数据。

现在您可以使用并执行SQL任务来获取每个键的记录之一(请参阅@Quassnoi了解如何执行此操作,以便您可能需要根据自己的情况调整查询)。就我个人而言,我将身份证放入暂存表中,以便我可以确定哪些是重复数据的首次发生或最后发生。然后将您为每个键选择的记录放入第二个登台表中。如果您使用的是异常表,请复制您未转移的记录,并且不要忘记异常的原因码(例如“重复键”)。

既然您在临时表中每个键只有一条记录,那么接下来的任务就是决定如何处理不是唯一的其他数据。如果同一客户有两个不同的商户地址,您选择哪一个?这是业务规则定义的问题,严格来说不是SSIS或SQL代码。当数据需要在两条记录之间合并时,您必须为您如何选择数据定义业务规则(您正在做的是等价于删除过程)。如果幸运的话,可以通过日期字段或其他方式来确定哪些是最新或最旧的数据,这是他们希望您使用的数据。在这种情况下,一旦你选择了一条记录,你就完成了初始化变换。

尽管您可能需要不同的规则才能选择正确的字段,在这种情况下,您可以在数据流或Exec SQl任务中编写SSIS转换以选择正确的数据并更新登台表。

一旦你有想要导入的确切记录,然后做数据流移动到正确的生产表。