Estou movendo registros de um banco de dados para outro, como parte do processo de arquivamento. Desejo copiar as linhas para a tabela de destino e excluir as mesmas linhas da tabela de origem.
Minha pergunta é, qual é a maneira mais eficiente de verificar se a primeira inserção foi bem-sucedida antes de excluir as linhas.
Minha ideia é essa, mas sinto que há uma maneira melhor:
@num_records=select count(ID) from Source_Table where (criteria for eligible rows)
insert * into Destination_Table where (criteria for eligible rows)
if ((select count(ID) from Destination_Table where (criteria) )=@numrecords)
delete * from Source_Table where (criteria)
É melhor/possível combiná-lo com a função RAISERROR? Obrigada!
Se sua tabela de arquivo não .
Você também pode fazê-lo em uma declaração.
Isso terá sucesso ou falhará como uma unidade e também evitará possíveis condições de corrida com linhas sendo adicionadas entre
INSERT
o arquivo eDELETE
(embora suaWHERE
cláusula possa tornar isso extremamente improvável de qualquer maneira).Eu recomendaria a sintaxe TRY/CATCH junto com transações explícitas. Minha suposição para esta solução é que o motivo da falha de inserção é algum tipo de erro de SQL interceptável (como uma violação de chave, incompatibilidade de tipo de dados/erro de conversão etc.). A estrutura ficaria assim:
Da forma como essa estrutura funciona, se ocorrer algum erro no INSERT ou no DELETE, toda a ação é revertida. Isso garante que toda a ação deve ser bem sucedida para ser concluída. Se você achasse que era necessário, você poderia combiná-lo com THROW para 2012 ou RAISERROR em 2008 e anteriores para adicionar lógica adicional e forçar uma reversão se essa lógica não fosse atendida.
Outra opção é olhar para SET XACT_ABORT ON , embora eu sinta que a sintaxe TRY/CATCH oferece mais granularidade.
A maneira que eu pensei em fazer o arquivamento (que eu tenho certeza que também não é perfeito), é adicionar uma coluna de bits à nova tabela de arquivo como 'Arquivado' que teria o valor de 1 após a transferência bem-sucedida de um registro. E uma vez que você transfere todos os registros, você pode executar uma operação de exclusão enquanto também procura por este valor de campo 'Arquivado' de '1', ou seja, True da tabela arquivada.
E eu concordo com Mike em usar Try/Catch.
Tente isto: