【发布时间】:2019-05-24 06:50:33
【问题描述】:
我浏览了很多关于 SO 的帖子。但是,它们不适合我的情况。
我们有一种情况,我们希望将sqlserver 2017 上的大型数据集存储到多个参考表中。
我们已经尝试使用cursor,它工作正常。但是,我们担心加载大数据(1+ 百万行)的性能问题
示例
T_Bulk 是输入表,T_Bulk_Orignal 是目标表,T_Bulk_reference 是 t_Bulk_orignal 的参考表
create table T_Bulk
(
Id uniqueidentifier,
ElementType nvarchar(max),
[Description] nvarchar(max)
)
create table T_Bulk_orignal
(
Id uniqueidentifier,
ElementType nvarchar(max),
[Description] nvarchar(max)
)
create table T_Bulk_reference
(
Id uniqueidentifier,
Description2 nvarchar(max)
)
create proc UseCursor
(
@udtT_Bulk as dbo.udt_T_Bulk READONLY
)
as
begin
DECLARE @Id uniqueidentifier, @ElementType varchar(500), @Description varchar(500),@Description2 varchar(500)
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT Id, ElementType, [Description]
FROM dbo.T_BULK
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @Id, @ElementType, @Description,@Description2
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN Transaction Trans1
BEgin TRy
IF EXISTS (select Id from T_Bulk_orignal where ElementType=@ElementType and Description=@Description)
select @Id = Id from T_Bulk_orignal where ElementType=@ElementType and Description=@Description
ELSE
BEGIN
insert T_Bulk_orignal(Id,ElementType,Description) values (@id, @ElementType,@Description)
END
INSERT T_Bulk_reference(Id,description2)
SELECT Id, Description2
FROM (select @Id as Id, @Description2 as Description2) F
WHERE NOT EXISTS (SELECT * FROM T_Bulk_reference C WHERE C.Id = F.Id and C.Description2 = F.Description2);
COMMIT TRANSACTION [DeleteTransaction]
FETCH NEXT FROM MY_CURSOR INTO @Id, @ElementType, @Description,@Description2
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Trans1]
SELECT @@Error
END CATCH
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
end
我们希望此操作像批量插入一样一次性执行,但是我们还需要交叉检查任何数据差异,如果无法插入一行,我们只需要回滚该特定记录
批量插入的唯一问题是存在参考表数据。
请就此提出最佳方法
【问题讨论】:
标签: sql sql-server tsql sql-server-2016 bulkinsert