更新或插入 SQL Server 时忽略错误行
Posted
技术标签:
【中文标题】更新或插入 SQL Server 时忽略错误行【英文标题】:Ignore error row when update or insert SQL Server 【发布时间】:2013-06-15 20:07:24 【问题描述】:我的项目必须处理庞大的数据库。在最坏的情况下,它可能超过 8000 万行。
现在,我有 2 张桌子 T1
和 T2
。我必须将数据从表T1
复制到表T2
T1
中的一行已经存在于表T2
中(相同的主键),则将T1
中该行的其他列的数据更新为T2
否则将新行插入T2
首先,我使用 while 循环遍历 T1
中的 8000 万行,然后更新或插入到 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 个表并找到不同的行。这些行是错误行。
【问题讨论】:
【参考方案1】:您可以尝试从 T2 中删除现有行,然后从 T1 中批量插入所有行。这取决于现有行数,如果太大,则此方法不起作用。
【讨论】:
【参考方案2】:至于您要求的功能,我建议如下:
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])
;
至于忽略错误 - 我认为这种方式是错误的。在这方面我会在数据验证上投入一些精力
【讨论】:
谢谢。运行这些错误:Msg 4104, Level 16, State 1, Line 7 The multi-part identifier "SOURCE.ID" could not be bound. 您能否检查一下您在“unsing”中的选择语句是否有效。它可能会发生,而不是重复相同的错误。如果它会 - 比你应该在你的 SELECT 中寻找问题 谢谢。我已经用第二种方法解决了这个问题。我使用 TRY_CAST 来防止插入或更新行时出现异常。任何无效的数据都将为 NULL。完成后,我比较了 2 个表并找到不同的行。这些行是错误行。【参考方案3】:我已经用第二种方法解决了这个问题。我使用 TRY_CAST 来防止插入或更新行时出现异常。任何无效的数据都将为 NULL。完成后,我比较了 2 个表并找到不同的行。这些行是错误行。
【讨论】:
以上是关于更新或插入 SQL Server 时忽略错误行的主要内容,如果未能解决你的问题,请参考以下文章
sql:mysql:MySql 不存在则插入,存在则更新或忽略
sql:mysql:MySql 不存在则插入,存在则更新或忽略