使用批量插入和触发器更新存储过程中的键冲突

问题描述 投票:0回答:1

我有一个存储过程,该过程执行大量DNS日志条目的批量插入。我希望将此原始数据汇总在一个新表中以进行分析。新表采用FQDN和记录类型的给定日志条目,并且仅保留具有命中数的一条记录。

源表可能包含100行:

FQDN, Type
www.microsoft.com,A

目标表将具有:

FQDN, Type, HitCount
www.microsoft.com, A, 100

SP建立由[FQDN] +'|'+ [Type]组成的唯一ID,然后将其用作目标表中的主键。

我的计划是让SP触发执行UPDATE ... IF @@ ROWCOUNT = 0 ... INSERT的触发器。但是,那当然失败了,因为触发器将所有[插入的]行作为一个单独的集合接收,因此总是抛出键冲突错误。

我很难找到解决方案,需要一些新鲜的眼睛和更好的技能才能看一眼。批量插入SP正常工作,原始数据完全符合要求。但是,尝试提出一种合适的方法来创建摘要数据的方法超出了我目前的技能/思维方式。

我需要处理数十个Tb的数据,因此我认为摘要不是我们可以通过SELECT COUNT动态执行的事情-这就是为什么我开始触发路线的原因。

SP中的相关代码由游标驱动,该游标由需要解压缩并批量插入的压缩日志文件列表组成,如下所示:

-- Bulk insert to a view because bulk insert cannot populate the UID field
SET @strDynamicSQL = 'BULK INSERT [DNS_Raw_Logs].[dbo].[vwtblRawQueryLogData] FROM ''' + @strTarFolder + '\' + @strLogFileName + ''' WITH (FIRSTROW = 1, FIELDTERMINATOR = '' '', ROWTERMINATOR = ''0x0a'', ERRORFILE = ''' + @strTarFolder + '\' + @strErrorFile + ''', TABLOCK)'
--PRINT @strDynamicSQL
EXEC (@strDynamicSQL)

-- Update [UID] field after the bulk insert
UPDATE [DNS_Raw_Logs].[dbo].[tblRawQueryLogData]
    SET [UID] = [FQDN] + '|' + [Type]
    FROM [tblRawQueryLogData]
    WHERE [UID] IS NULL

我知道UPDATE ... IF @@ ROWCOUNT = 0 ... INSERT解决方案是错误的,因为它假定输入数据是单行。我很乐意为您提供帮助。谢谢

sql-server tsql stored-procedures bulkinsert
1个回答
0
投票

首先,要确保您了解columnstore tables。它们被高度压缩并且可以快速扫描。

然后编写一个从原始表中读取并返回摘要的查询

创建或更改视图DnsSummary如选择FQDN,类型,计数(*)HitCount来自tblRawQueryLogData按FQDN分组,类型

然后,如果直接查询该视图过于昂贵,请编写一个存储过程,在每次批量插入后加载一个表。或将视图放入indexed view

© www.soinside.com 2019 - 2024. All rights reserved.