我在 SO 上浏览了很多帖子。但是,它们不适合我的情况。
在某些情况下,我们要将sqlserver 2017
上的大型数据集存储到多个参考表中。
我们已经尝试使用cursor
,并且工作正常。但是,我们担心加载大数据(1+百万行)的性能问题
示例
T_Bulk 是一个输入表, T_Bulk_Orignal 是目标表, T_Bulk_reference 是 t_Bulk_orignal < / p>
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
我们希望此操作像批量插入一样一次性执行,但是我们还需要交叉检查任何数据差异,如果无法插入一行,我们只需要回滚该特定记录
批量插入的唯一障碍是存在参考表数据。
请为此建议最佳方法
答案 0 :(得分:0)
这听起来像是SSIS(SQL Server Integration Services)的工作。 https://docs.microsoft.com/en-us/sql/integration-services/ssis-how-to-create-an-etl-package
在SSIS中,您可以创建可以进行引用检查的数据迁移作业。您可以将其设置为在每个阶段失败,警告或忽略错误。要在此Google上查找ETL和SSIS的资源。
我完成了超过50百万行的像您一样的工作。
当然要花一些时间,并且会在出现错误时回滚所有内容(如果这样设置),但这是进行此类工作的最佳工具。
答案 1 :(得分:0)
我有一个解决方案,可以像批量插入一样上传大型文件。
SQL中存在一个Merge
语句。
MERGE语句用于根据以下内容在一个表中进行更改 从花药匹配的值。它可以用于结合插入, 更新和删除操作成一条语句
因此我们可以使用DataTable
将数据传递到StoredProcedure
,然后Source将是您的UserDefinedDataTable
,而Target将是您实际的SQL Table