Olá pessoal,
Bom tarde!
Neste post vou demonstrar a vocês como prevenir um tipo de problema no SQL Server que pode causar muito transtorno na vida de uma DBA, e demora um bom tempo para resolver e pode ser facilmente evitado e monitorado, que é quando uma coluna IDENTITY acaba atingindo o valor limite do seu tipo de dado e ao tentar inserir novos registros na tabela, você verá uma mensagem de erro como essa:
Msg 8115, Level 16, State 1, Line 18
Arithmetic overflow error converting IDENTITY to data type tinyint.
Arithmetic overflow occurred.
Esse erro ocorre porque cada tipo de dado possui um valor máximo em que ele pode atingir. O DBA precisa sempre monitorar se esse valor não está chegando próximo do limite, pois quando isso acontece, novos registros não são gravados.
Num cenário de produção, isso é um desastre para a empresa e mesmo que o DBA tente agir rapidamente, uma operação de alteração de tipo, principalmente quando a tabela estoura o INT, demora muito para ser realizada e isso no meio do horário comercial, é realmente um problema gravíssimo.
Os tipos de dados mais utilizados em colunas com IDENTITY e os valores permitidos são:
Tipo de dado | Intervalo |
---|---|
tinyint | 0 a 255 (1 byte) |
smallint | -32.768 a 32.767 (2 bytes) |
int | -2.147.483.648 a 2.147.483.647 (4 bytes) |
bigint | -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 (8 bytes) |
Apesar de ter listado apenas os tipos acima, você também possa utilizar NUMERIC e DECIMAL para formar seu IDENTITY, embora não seja muito comum. Entretanto, o tamanho máximo do NUMERIC e DECIMAL vai depender da escala e precisão que você declarar na coluna.
Neste post, também vamos monitorar as SEQUENCES, que foram implementadas a partir do SQL Server 2012, e que também podem acabar atingindo o limite e gerar sérios problemas em produção. Caso você não conheça o recurso SEQUENCE do SQL Server, dê uma lida no post Trabalhando com Sequences no SQL Server.
Uma forma prática de simular esse problema, é executando os comandos abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
CREATE TABLE #TesteTinyInt ( Id TINYINT IDENTITY(1, 1), Name VARCHAR(50) ) DECLARE @Contador INT = 1, @Total INT = 255 WHILE(@Contador <= @Total) BEGIN INSERT INTO #TesteTinyInt ( Name ) VALUES ( ' Teste ' + CAST(@Contador AS VARCHAR(10)) ) SET @Contador += 1 END -- Aqui vai dar erro INSERT INTO #TesteTinyInt ( Name ) VALUES ( ' Teste Overflow ' ) |
Caso você queira criar um monitoramento desse tipo de situação ou apenas visualizar como está a situação atual dos databases da sua instância, basta executar a query abaixo (também monitora o valor máximo de SEQUENCES):
Exibir o código-fonte
Se você não tem uma base para realizar esse teste e deseja criar a sua apenas para visualizar como é o resultado, utilize essa query:
Exibir o código-fonte
And that's it, folks!
Espero que tenham gostado desse post e até a próxima.
Como corrigir?
Parabéns Dirceu, mais um excelente artigo para sua coleção!
Obrigado pelo feedback, Caio. Abraço.