2013-06-19 116 views
0

我的项目必须处理庞大的数据库。在最坏的情况下,它可以是超过80百万行。更新或插入SQL Server时忽略错误行

现在,我有2个表T1T2。我必须将数据从表T1复制到表T2

  • 如果表T1一个行表T2(同一主键)已经存在,则更新T1该行的其他列数据T2
  • 否则插入新行到T2

起初,我用while循环遍历80个百万行T1然后更新或插入到T2。这非常非常慢,完成需要超过10个小时。但是,如果任何行导致错误,我可以忽略它,并捕捉错误。

在那之后,我喜欢用一个查询:

update Table2 
set T2.Column1 = T1.Column1,T2.Column2=T1.Column2 
from Table2 T2 JOIN Table1 T1 ON T1.ID=T2.ID 

这是更快,只需要大约1> 2小时完成。但是,如果任何行有错误,则查询根本无法执行。

所以,我的问题是:

  • 有什么办法,上面的查询可以忽略错误行并继续有效行执行?

  • 如果没办法,我可以做到这一点,我能做些什么来比第一种方法运行更快,也可以捕获错误行?

P/S:我试图将表拆分到多个小部分,然后更新或在同一时间插入所有小部分,但它确实不是更快的。

我已经用我的第二种方法解决了这个问题。在插入或更新行时,我使用TRY_CAST来防止发生异常。任何无效的数据都将为NULL。完成后,我比较2个表并找到不同的行。这些行是错误行。

回答

0

我用我的第二种方法解决了这个问题。在插入或更新行时,我使用TRY_CAST来防止发生异常。任何无效的数据都将为NULL。完成后,我比较2个表并找到不同的行。这些行是错误行。

0

至于功能,你所要求的,我建议如下:

MERGE INTO table2 target 
USING 
(
    SELECT id, column1, column2 FROM table1 
) source ([id], [column1], [column2]) 
ON target.[Id] = source.[Id] 
WHEN MATCHED THEN 
    UPDATE SET 
     target.Colum1 = source.Column1, 
       target.COlumn2 = source.Column2 
WHEN NOT MATCHED BY SOURCE THEN 
DELETE 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT ([Id], [Column1], [Column2]) 
    VALUES([Id], [Column1], [Column2]) 
; 

至于忽略的错误 - 我看到这样的错误的。在这方面,我会投入一些努力数据验证

+0

谢谢。运行这些错误:Msg 4104,Level 16,State 1,Line 7 无法绑定多部分标识符“SOURCE.ID”。 – user2500561

+0

你可以检查你的select语句是否在“unsing”中一起工作。它可能发生的错误将会重复。如果它会 - 比你应该在你的SELECT中寻找问题 –

+0

谢谢。我用第二种方法解决了这个问题。在插入或更新行时,我使用TRY_CAST来防止发生异常。任何无效的数据都将为NULL。完成后,我比较2个表并找到不同的行。这些行是错误行。 – user2500561

0

您可以尝试从T2中删除现有的行,然后批量插入从T1的所有行。它取决于现有行的数量,如果它太大,那么这种方法将无法工作。