我有一个夜间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连接连接到大型机。
我怀疑我的问题可能没有“简单”的解决方案。但是,我希望我错了。
答案 0 :(得分:2)
由于您使用的是SSIS,因此您必须使用OLE DB Source
从AS400获取数据,并且您将使用OLE DB Destination
将数据插入SQL Server。
假设您没有任何转换
在OLE DB源之后添加Sort transformation
。在排序转换中,底部有一个复选框选项,用于根据给定的列值集删除重复的行。检查所有字段,但不要选择来自AS400的主键。这将消除重复的行,但会插入您仍需要的数据。
我希望这就是你要找的东西。
答案 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转换,以选择正确的数据并更新登台表。
获得要导入的确切记录后,请执行数据流以移至正确的生产表。