Я пытаюсь обработать документ Excel с 2 листами. 1-й лист содержит метаданные, а 2-й лист - фактические данные.
1-й лист содержит 10 столбцов, а второй - не менее 50 столбцов и может варьироваться. Прежде чем помещать данные в базу данных SQL Server, мне нужно проверить каждую ячейку листа. Некоторые из них являются только проверкой типа данных для листа, а некоторые столбцы необходимо проверить по значениям базы данных и соответствующим образом создать объект ошибки в случае сбоя.
Кроме того, сначала должны быть обработаны данные листа заголовка, а затем фактические данные. Отображения для заголовка и таблицы данных хранятся в базе данных и проверяются. Поскольку в заголовке не будет более 1000 записей, я обрабатываю и помещаю данные заголовка в базу данных за один раз.
Я преобразую столбцы таблиц данных в один объект json для строки, а затем для каждых 5000 строк я вызываю хранимую процедуру для вставки этих записей в базу данных.
Весь этот процесс проверки, создания объектов ошибок и отправки данных для почти 0,1 миллиона записей занимает почти 20 минут.
Есть ли способ, которым я могу сделать это быстрее? В будущем мы можем получить более 1 миллиона записей на листе.
Поскольку в хранимых процедурах также задействовано много логики, опция SqlBulkCopy
здесь также не подходит.
CREATE PROCEDURE [dbo].[sp_AddData] (
@Table DataTable READONLY,
@DocumentType NVARCHAR(20)
)
AS
BEGIN
IF(@DocumentType = 'abcd')
BEGIN
INSERT INTO dbo.Table1 (
DMDId,
SN,
Name,
Date,
GP,
D,
NP,
Data,
IsLatest
)
SELECT
DMD.Id,
PDDT.SN,
PDDT.Name,
PDDT.Date,
PDDT.GP,
PDDT.D,
PDDT.NP,
PDDT.Data,
1
FROM @Table PDDT
INNER JOIN dbo.Table2 DMD
ON DMD.TY = PDDT.TY AND
DMD.TP = PDDT.TP AND
DMD.IsLatest = 1
INNER JOIN dbo.Table3 P
ON P.CPID = PDDT.CPID AND
DMD.PID = P.Id
END
END
GO
CREATE TYPE [dbo].[DataTable] AS TABLE
(
[Id] [INT] NULL,
[SN] [NVARCHAR](50) NOT NULL,
[Name] [NVARCHAR](50) NOT NULL,
[Date] [DATETIME] NOT NULL,
[GP] [NUMERIC](22,2) NOT NULL,
[D] [NUMERIC](22,2) NOT NULL,
[NP] [NUMERIC](22,2) NOT NULL,
[Data] [NVARCHAR](MAX) NOT NULL,
[TP] [INT] NOT NULL,
[TY] [NVARCHAR](20) NOT NULL,
[CPId] [NVARCHAR](30) NOT NULL
)
GO