SQL插入不同的记录

时间:2016-04-12 16:57:38

标签: sql sql-server sql-update distinct

我试图批处理一些插入脚本(避免重复)并且我遇到了一些没有主键的表(我知道......我没有创建它们而我不能修改它们)。基本上我所做的就是抓住我需要的行,将它们放入临时表([TempTable])中,并更新其中的一些值。

现在,我需要批量将DISTINCT TOP中的[TempTable]值重新插入[OriginalTable]。要做到这一点,我想我需要一个临时表中的列(我已经创建了......让它称之为[ValuesInserted]),它指定了刚插入的列。

我会使用INSERT声明将DISTINCT值放入原始表格中,然后使用TOP对其进行批处理。

INSERT INTO [OriginalTable]
SELECT DISTINCT TOP (1000) *
FROM [TempTable]

然后我会更新临时表,将ValuesInserted设置为1,用于刚刚插入的记录。 这就是我被困的地方:

UPDATE /*TOP (1000) - Doesn't work*/ [TempTable]
SET [ValuesInserted] = 1
???

然后我将从临时表中删除这些记录,以便我的下一个INSERT语句(使用TOP)不会捕获前一组记录。

DELETE
FROM [TempTable]
WHERE [ValuesInserted] = 1

我遇到的主要问题是仅在UPDATE行上运行TOP (1000),并未捕获{{1}中可能包含重复项的所有记录}}。我也无法对[TempTable]的两个副本上的所有列执行INNER JOIN,因为这是使用动态SQL在许多不同的表上运行的。基本上,脚本需要是通用的(不是特定于任何表),但应该假设没有主键。

以下通用示例捕获了这个想法:

[TempTable]

对上述数据集执行Val1 Val2 ValuesInserted 1 1 0 1 2 0 1 3 0 1 4 0 1 5 0 1 6 0 1 7 0 1 8 0 1 9 0 1 1 0 <--Duplicate 2 1 0 2 2 0 2 3 0 2 4 0 2 5 0 2 6 0 2 7 0 2 8 0 2 9 0 2 1 0 <--Duplicate 3 1 0 3 2 0 3 3 0 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 1 0 <--Duplicate 1 2 0 <--Duplicate 1 3 0 <--Duplicate 只会更新前5条记录:

UPDATE TOP (5)

我需要更新与前5条记录匹配的所有记录,如下所示:

Val1    Val2    ValuesInserted
1       1       1             <--Updated
1       2       1             <--Updated
1       3       1             <--Updated
1       4       1             <--Updated
1       5       1             <--Updated
1       6       0
1       7       0
1       8       0
1       9       0
1       1       0             <--Duplicate
2       1       0
2       2       0
2       3       0
2       4       0
2       5       0
2       6       0
2       7       0
2       8       0
2       9       0
2       1       0             <--Duplicate
3       1       0
3       2       0
3       3       0
3       4       0
3       5       0
3       6       0
3       7       0
3       8       0
3       9       0
3       1       0             <--Duplicate
1       2       0             <--Duplicate
1       3       0             <--Duplicate

如果您可以将您的想法用于此示例,我可以将其应用于我的具体案例。

我接近这个完全错误,还是我错过了什么?我正在寻找不会占用资源的解决方案,因为脚本是经过批处理的,并且在高影响力服务器上的非常大的数据库上运行。

我能找到的最接近的主题是: Using Distinct in SQL Update。 但是,使用Val1 Val2 ValuesInserted 1 1 1 <--Updated 1 2 1 <--Updated 1 3 1 <--Updated 1 4 1 <--Updated 1 5 1 <--Updated 1 6 0 1 7 0 1 8 0 1 9 0 1 1 1 <--Updated 2 1 0 2 2 0 2 3 0 2 4 0 2 5 0 2 6 0 2 7 0 2 8 0 2 9 0 2 1 0 <--Duplicate 3 1 0 3 2 0 3 3 0 3 4 0 3 5 0 3 6 0 3 7 0 3 8 0 3 9 0 3 1 0 <--Duplicate 1 2 1 <--Updated 1 3 1 <--Updated 时,给出的答案无效。

编辑:这显然在开始时并不清楚。我要做的第一件事是从TOP抓取行并将它们放入[OriginalTable]。这些行最初是唯一的。但是,我执行更新来修改某些值,产生类似上面示例的数据。 从那里,我需要抓取[TempTable]行并将其重新插入DISTINCT

1 个答案:

答案 0 :(得分:2)

看起来你真的想要尽可能地让它变得复杂。我首先要从临时表中删除重复项。或者从来没有INSERT他们,这甚至更好。或者使用SSIS构建一个实际的ETL解决方案。

这些事情说明了,您正在寻找的是OUTPUT条款,可以将其添加到任何INSERTUPDATEDELETE语句中:

DECLARE @inserted_ids TABLE (val1, val2)

INSERT INTO dbo.OriginalTable (val1, val2)
OUTPUT INSERTED.val1, INSERTED.val2 INTO @inserted_ids
SELECT DISTINCT TOP 1000 val1, val2
FROM dbo.TempTable

DELETE TT
FROM @inserte_ids II
INNER JOIN dbo.TempTable TT ON
    TT.val1 = II.val1 AND
    TT.val2 = II.val2