SQL Server na prática

SQL Server OUTPUT: capturar as alterações corretas

Obtenha chaves e valores anteriores e novos com OUTPUT, considerando ordem, triggers, falhas transacionais e correlação.

Atualizar linhas e consultá-las depois faz duas perguntas diferentes: quais linhas a instrução mudou e o que as linhas correspondentes contêm agora. Sob concorrência, essas respostas podem divergir. OUTPUT vincula o resultado à própria modificação, permitindo capturar chaves geradas e valores anteriores e novos com associação precisa.

Capturar uma relação estável

O exemplo usa tabelas temporárias e altera duas linhas de estoque. Ele captura chave, quantidade anterior e quantidade nova do mesmo UPDATE. O ORDER BY final organiza a apresentação sem depender da ordem física de atualização.

IF @@TRANCOUNT <> 0
    THROW 50000, 'This example owns its transaction.', 1;
SET XACT_ABORT ON;
CREATE TABLE #Stock (ItemId int PRIMARY KEY, Qty int NOT NULL);
INSERT #Stock VALUES (1, 12), (2, 20);
CREATE TABLE #Changed (ItemId int, OldQty int, NewQty int);
BEGIN TRY
    BEGIN TRAN;
    UPDATE #Stock
    SET Qty = Qty - 2
    OUTPUT inserted.ItemId, deleted.Qty, inserted.Qty
        INTO #Changed(ItemId, OldQty, NewQty)
    WHERE ItemId IN (1, 2) AND Qty >= 2;
    COMMIT;
    SELECT ItemId, OldQty, NewQty FROM #Changed ORDER BY ItemId;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 ROLLBACK;
    THROW;
END CATCH;

Mantenha a chave na saída. Retornar apenas quantidades obriga o cliente a adivinhar a associação. Para inserções de várias linhas, preserve uma correlação única fornecida pelo cliente e devolva-a junto com a identidade gerada. Não associe a primeira identidade recebida à primeira entrada: essa ordem não é garantida.

Capture somente colunas necessárias. OUTPUT inserted.* acopla a API à estrutura inteira e pode copiar valores grandes sem necessidade. Uma lista explícita torna mudanças de tipos visíveis e evita exposição acidental de campos internos.

Separar saída de confirmação

A fronteira transacional continua decisiva. OUTPUT não comprova que a transação de negócio foi confirmada. Uma instrução posterior pode falhar, ocorrer rollback ou a conexão desaparecer durante a confirmação do commit. O aplicativo precisa consumir o resultado completo e seus erros antes de considerar a operação bem-sucedida.

O padrão captura em tabela temporária, confirma e só então devolve linhas. Se algo falhar, CATCH desfaz e propaga o erro em vez de selecionar uma resposta de sucesso. A verificação impede transação externa, pois o chamador ainda poderia desfazê-la depois de receber essa resposta.

Isso resolve a sequência local, não a perda de resposta. Se o commit terminar sem que o cliente receba o resultado, uma nova tentativa precisa de identificador durável para encontrar a operação anterior. A tabela temporária desaparece com a sessão. Grave correlação e resultado permanentemente quando a API precisar de escritas seguras para repetição.

Definir limites de triggers e auditoria

Os valores inserted de OUTPUT refletem a modificação antes dos triggers AFTER. Se um trigger normalizar algum valor depois, a saída pode diferir do conteúdo final. Determine qual contrato o cliente precisa. Para valores definitivos, capture chaves e planeje uma leitura final com isolamento adequado em uma transação claramente definida.

OUTPUT direto também possui restrições quando há triggers habilitados para a ação. OUTPUT INTO pode ser apropriado, mas seu destino tem limitações próprias. Verifique o esquema verdadeiro, não apenas uma tabela vazia de demonstração.

Uma resposta enviada ao cliente não é auditoria durável. Uma tabela de auditoria gravada na mesma transação acompanha alterações confirmadas, mas sua escrita também é desfeita no rollback. Registrar tentativas malsucedidas exige outro desenho. Diferencie alterações concluídas, tentativas e a necessidade eventual de ambas.

Por fim, meça o custo da captura em grandes modificações. Milhões de valores anteriores e novos podem consumir memória, log e rede. Uma resposta estreita com chave e estado pode atender melhor. Teste sucesso, falha forçada, valores alterados por trigger e correlação de várias entradas. Confira especialmente se o cliente descarta linhas já observadas quando um erro posterior invalida o resultado do comando, em vez de tratá-las como alterações confirmadas.

Referências técnicas: Microsoft Learn: OUTPUT · Microsoft Learn: TRY CATCH.

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