Gostaria de adicionar informações de versão ao nosso BD - tudo o que será usado é para verificar se a versão do usuário de uma linha mudou desde que ele a leu. Estou pensando em adicionar uma coluna chamada _VERSION
às duas dúzias de tabelas em questão. Como parte de uma UPDATE
declaração em lote, eu teria algo como SET ..._VERSION=something_or_other
. Sou agnóstico sobre quais dados essa coluna contém.
Uma solução que vi é usar uma coluna datetime e então obter o horário de início da transação de sys.dm_tran_active_transactions, selecionando a linha para CURRENT_TRANSACTION_ID()
. Para nossas necessidades, a precisão de 1/300 será mais do que suficiente. Entendo que usar CURRENT_TIMESTAMP
não é tão útil nessa situação porque isso mudará conforme o lote prossegue.
Se isso for canônico, farei isso. É fácil de implementar.
Mas essa é a melhor maneira para usos realmente simples? Existe algum outro valor no sys.dm_tran...
que fornece o mesmo resultado, mas pode ser mais fácil de armazenar e WHERE do que um datetime?
OBSERVAÇÃO: sim, estou ciente das tabelas temporais e do rastreamento de alterações da MS e me disseram para não usá-los.
Você não precisa de nenhum tempo de transação.
o tipo rowversion é introduzido para ele
O tipo de dados rowversion é apenas um número incremental e não preserva uma data ou hora.
Outra resposta sugere adicionar uma
rowversion
coluna às suas tabelas. Isso pode funcionar muito bem, mas você pode ficar infeliz se suas tabelas forem grandes e altamente transacionais, pois pode haver um bloqueio significativo ao adicionar essas colunas. Também não há grandes truques ou atalhos para isso, que eu tenha visto.Talvez seja melhor adicionar uma coluna não-NULLable com um valor padrão às suas tabelas —
datetime2(0)
seria bom — já que essa é uma alteração somente de metadados para a maioria das versões modernas do SQL Server (ao contrário darowversion
alteração) e usarAFTER
gatilhos para manter o controle de instruções concluídas com sucessoUPDATE
. Você não precisa deles para consultasINSERT
ouDELETE
por motivos óbvios:SYSDATETIME()
para quando forem inseridasTorna as coisas bem simples.
com script
Para a coluna:
Para o gatilho:
Teste, 1-2-3:
Resultados:
Para o gatilho, você pode usar a tabela virtual
Inserted
ouDeleted
. Não importa aqui, porque ambas conterão o mesmo conjunto básico de linhas.Importaria se você quisesse a imagem anterior (
Deleted
tabela) ou posterior (Inserted
tabela) para usar os resultados para auditar os valores realmente alterados.Uma resposta brilhante no StackOverflow por @MartinSmith usa um recurso CDC, mas sem realmente aplicar o CDC à tabela.
Tem algumas limitações.
Note que não há uma tabela de histórico de Tabelas Temporais aqui, é apenas um par de colunas de atualização automática. Então isso não deve ser um problema se você estiver preocupado com o desempenho da Tabela Temporal.