SQL Server na prática

Construir uma importação recuperável no SQL Server

Separe carga bruta, validação e publicação para tratar arquivos inválidos e novas tentativas sem deixar tabelas de produção parcialmente preenchidas.

Uma carga rápida é apenas parte de uma importação confiável. Depois é preciso explicar rejeições, reconhecer um arquivo já processado e impedir que usuários enxerguem metade do conjunto de dados. Uma área de staging deixa essas responsabilidades explícitas.

Preservar a entrada antes de interpretar

Atribua um identificador estável ao lote e guarde identidade do arquivo, hash do conteúdo, chegada e versão do parser. O nome não basta, pois o fornecedor pode reutilizá-lo com outro conteúdo. Preserve campos originais e uma identificação do registro de origem para localizar erros.

Carregue primeiro em uma área isolada. BULK INSERT usa um caminho acessível pelo host SQL Server ou pela fonte configurada, não pelo notebook do analista. Confirme a identidade de acesso e o contrato de formato. Teste codificação, campos vazios, delimitadores entre aspas e quebras de linha internas.

Uma linha física nem sempre representa um registro CSV lógico. Se posições exatas forem necessárias, o parser precisa registrá-las. Um identity gerado no staging não comprova automaticamente a ordem original do arquivo.

O exemplo começa depois do parsing e usa strings brutas para mostrar a fronteira de validação. Ele não é um parser CSV completo.

DECLARE @Raw TABLE
(
    SourceRow int PRIMARY KEY,
    CustomerText nvarchar(100),
    DateText nvarchar(100),
    AmountText nvarchar(100)
);
INSERT @Raw VALUES
(1, N'42', N'20260601', N'125.50'),
(2, N'bad', N'20260602', N'20.00'),
(3, N'43', N'20260230', N'15.00'),
(4, N'44', N'20260603', N''),
(5, N'45', N'20260604', N'-7.00');

SELECT r.*,
    TRY_CONVERT(int, NULLIF(LTRIM(RTRIM(CustomerText)), N'')) AS CustomerId,
    TRY_CONVERT(date, NULLIF(LTRIM(RTRIM(DateText)), N''), 112) AS InvoiceDate,
    TRY_CONVERT(decimal(19,4), NULLIF(LTRIM(RTRIM(AmountText)), N'')) AS Amount
INTO #Parsed
FROM @Raw AS r;

SELECT SourceRow, CustomerId, InvoiceDate, Amount,
    CASE
        WHEN CustomerId IS NULL OR CustomerId <= 0 THEN N'Invalid customer'
        WHEN InvoiceDate IS NULL THEN N'Invalid date'
        WHEN Amount IS NULL OR Amount <= 0 THEN N'Invalid amount'
        ELSE N'Accepted'
    END AS ValidationResult
FROM #Parsed
ORDER BY SourceRow;

DROP TABLE #Parsed;

Somente a linha 1 é aceita. A 2 contém cliente inválido, a 3 uma data impossível, a 4 um valor vazio e a 5 um valor negativo. NULLIF impede tratar um campo numérico vazio como número útil. O estilo 112 define YYYYMMDD sem depender do idioma da sessão.

Transformar rejeições em resultado utilizável

TRY_CONVERT separa muitas falhas de conversão do fracasso do lote inteiro. Conversão bem-sucedida não significa validade de negócio. O exemplo aceita identificadores positivos sem provar que o cliente existe. Faça a verificação contra o conjunto autorizado antes da publicação.

Converter para decimal também pode arredondar casas adicionais. Se isso for proibido, valide a representação original ou compare com uma representação aceita mais precisa. O tipo da coluna não substitui a política de entrada.

CASE retorna apenas o primeiro erro de cada linha para facilitar a leitura. Uma tabela de erros pode guardar várias razões com lote, registro de origem, campo, código e valor original. Defina acesso e retenção adequados. Uma mensagem genérica de importação fracassada dificulta a correção pelo fornecedor.

Verifique duplicatas dentro do lote e contra a chave de negócio do destino. Decida se devem ser rejeitadas, substituídas ou agregadas deliberadamente. DISTINCT usado apenas para evitar erro de unicidade pode esconder um problema ou descartar uma diferença importante.

Reconcilie registros brutos, falhas de parsing, rejeições, aceitos e publicados. Defina as categorias para não contar várias vezes uma linha com vários erros. Guarde o resumo com o lote, permitindo conferir completude sem abrir novamente o arquivo.

Definir a fronteira de recuperação

Escolha entre publicação integral e aceitação parcial permitida. Para tudo ou nada, conclua a validação antes da transação curta que aplica os dados e marca o lote como publicado. As constraints do destino continuam necessárias porque referências podem mudar após os controles.

Imponha unicidade à identidade do lote ou operação. Se a conexão cair depois do commit, a próxima tentativa deve consultar o resultado registrado. O marcador de publicação e as alterações precisam confirmar juntos.

Importações grandes podem exigir partes limitadas, mas isso muda a recuperação. Registre partes concluídas e torne cada uma repetível, ou mantenha os dados invisíveis até um estado final respeitado por todos os leitores. Uma flag ignorada por um relatório não garante essa separação.

Meça parsing, joins de validação, crescimento do log, manutenção de índices e publicação em conjunto. Preserve rejeições pelo tempo necessário para correção e reprocessamento, depois aplique a política de exclusão. Uma importação é confiável quando explica seu resultado e consegue continuar com segurança, não apenas quando sua etapa de carga é rápida.

Referências técnicas: Microsoft Learn: BULK INSERT · Microsoft Learn: TRY_CONVERT.

Pergunte sobre este artigo

Tem alguma dúvida sobre este tema?

Conte o que você está avaliando ou onde encontrou dificuldades. Responderemos com uma recomendação prática.

Inquiries are not enabled in this preview.

Fazer uma pergunta sobre este artigo