我试图批处理一些插入脚本(避免重复)并且我遇到了一些没有主键的表(我知道......我没有创建它们而我不能修改它们)。基本上我所做的就是抓住我需要的行,将它们放入临时表([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
。
答案 0 :(得分:2)
看起来你真的想要尽可能地让它变得复杂。我首先要从临时表中删除重复项。或者从来没有INSERT
他们,这甚至更好。或者使用SSIS构建一个实际的ETL解决方案。
这些事情说明了,您正在寻找的是OUTPUT
条款,可以将其添加到任何INSERT
,UPDATE
或DELETE
语句中:
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