如何在准唯一数据键上创建主键?

时间:2011-08-04 15:46:37

标签: sql sql-server tsql ssis

我有一个夜间SSIS进程,可以从AS400数据库系统中导出TON数据。由于AS400 DB软件中存在错误,会在数据表中插入ocassional重复键。每次将新副本添加到AS400表时,它都会终止我的夜间导出过程。这个问题已经从麻烦转变为问题。

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

在我的情况下,更重要的是我的主键在我的SQL Server数据库缓存中保持唯一,而不是拥有完整的数据快照。我可以做些什么来强制对SSIS / SQL Server中的导出进行约束而不会导致进程崩溃吗?

修改

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

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

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

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

4 个答案:

答案 0 :(得分:2)

由于您使用的是SSIS,因此您必须使用OLE DB Source从AS400获取数据,并且您将使用OLE DB Destination将数据插入SQL Server。

假设您没有任何转换

Data Flow Task

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

Sort

我希望这就是你要找的东西。

答案 1 :(得分: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

答案 2 :(得分: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 

答案 3 :(得分:0)

如果我理解正确,那么您在其他字段中拥有不同数据的重复PK。

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

现在您可以使用和执行SQL任务来获取每个键的记录之一(请参阅@Quassnoi以了解如何执行此操作,您可能需要根据您的情况调整其查询)。我个人将一个标识放入我的临时表中,因此我可以确定哪个是重复数据的第一个或最后一个。然后将您为每个密钥选择的记录放入第二个临时表中。如果您正在使用异常表,请复制您未移动到的记录,并且不要忘记异常的原因代码(例如“重复密钥”)。

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

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

获得要导入的确切记录后,请执行数据流以移至正确的生产表。