Я просмотрел множество постов на 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
Мы хотим, чтобы эта операция выполнялась за один раз, как при массовой вставке, однако нам также необходимо провести перекрестную проверку любого несоответствия данных, и если одна строка не может быть вставлена, нам нужно откатить только эту конкретную запись
Единственный улов для массовой вставки - это наличие данных справочной таблицы.
Пожалуйста, предложите лучший подход к этому