Se você estiver recebendo o erro “Msg 8115, erro de estouro aritmético de nível 16 convertendo IDENTITY para tipo de dados… ” no SQL Server, provavelmente é porque você está tentando inserir dados em uma tabela quando sua
IDENTITY
coluna atingiu o limite de seu tipo de dados. Uma
IDENTITY
coluna incrementa automaticamente o valor que é inserido a cada nova linha. Se o valor que está sendo inserido estiver fora do intervalo do tipo de dados da coluna, ocorrerá o erro acima. Exemplo do erro
Aqui está um exemplo de código que resulta no erro:
INSERT INTO t1 VALUES ('Dog');
Resultado:
Msg 8115, Level 16, State 1, Line 1 Arithmetic overflow error converting IDENTITY to data type tinyint.
Neste caso, minha
IDENTITY
coluna usa o tinyint
tipo de dados, que tem um intervalo de 0 a 255. O erro implica que o IDENTITY
coluna está tentando inserir um valor maior que 255. Isso normalmente ocorre quando já inserimos 255 linhas na coluna e agora estamos tentando inserir a 256ª linha.
Esta é a aparência da minha tabela quando seleciono todas as linhas em que
IDENTITY
coluna é maior que 250
:SELECT * FROM t1
WHERE c1 > 250;
Resultado:
+------+------+ | c1 | c2 | |------+------| | 251 | Ant | | 252 | Cow | | 253 | Bat | | 254 | Duck | | 255 | Bull | +------+------+
Nesse caso,
c1
é minha IDENTITY
coluna (que por acaso é o tipo tinyint
). Podemos ver que IDENTITY
gerou anteriormente 255
para a coluna e, portanto, o próximo valor que tenta inserir é 256
(assumindo um valor de incremento de 1
e sem inserções com falha anterior). Isso causará o erro acima, porque 256 está fora do intervalo de um tinyint
. O mesmo problema pode ocorrer com tipos de dados de
smallint
(valor máximo de 32.767) ou int
(valor máximo de 2.147.483.647). Isso também pode acontecer com bigint
se você inseriu linhas suficientes (mais de 9.223.372.036.854.775.807). No entanto, a
IDENTITY
value nem sempre corresponde ao número de linhas inseridas. Você pode definir um valor de semente ao criar uma IDENTITY
coluna, e você também pode definir um valor de incremento. Portanto, você pode facilmente atingir o limite superior muito antes do número de inserções realizadas na tabela, dependendo dos valores de semente e incremento. Além disso, excluir linhas de uma tabela não redefine a
IDENTITY
value (embora truncar uma tabela faça). Portanto, você ainda pode enfrentar o erro acima mesmo quando houver muito menos linhas na tabela do que
IDENTITY
tipo de dados da coluna pode sugerir. Solução
Uma solução é alterar o tipo de dados da
IDENTITY
coluna. Por exemplo, se for smallint
, altere para int
. Ou se já for int
, altere para bigint
. Outra solução possível seria redefinir a
IDENTITY
semente para um valor mais baixo. Isso só funcionaria se você excluísse muitas linhas da tabela ou se o valor da semente original fosse muito maior que 1
. Por exemplo, se a
IDENTITY
coluna já é um int
, mas a IDENTITY
seed começou em, digamos, 2,000,000,000
, você pode redefinir a IDENTITY
semente para 1
, o que permitiria a inserção de mais 2 bilhões de linhas. Funções úteis
Aqui estão algumas funções que podem ser muito úteis para identificar esse problema:
IDENT_CURRENT()
– retorna o último valor de identidade gerado para uma tabela ou exibição especificada em uma coluna de identidade.@@IDENTITY
– Retorna o último valor de identidade inserido na sessão atual.IDENT_SEED()
– Retorna a semente original de uma coluna de identidade.IDENT_INCR()
– Retorna o valor de incremento de uma coluna de identidade.
Além disso, aqui estão 3 maneiras de obter o tipo de dados de uma coluna caso você não tenha certeza de qual é o tipo de dados da coluna.
Mesmo erro em cenários diferentes
O mesmo erro (Mensagem 8115) também pode ocorrer (com uma mensagem de erro ligeiramente diferente) quando você tenta converter explicitamente entre tipos de dados e o valor original está fora do intervalo do novo tipo. Consulte Corrigir “Erro de estouro aritmético ao converter int para tipo de dados numérico” no SQL Server para corrigir isso.
Também pode ocorrer quando você usa uma função como
SUM()
em uma coluna e o cálculo resulta em um valor que está fora do intervalo do tipo da coluna. Consulte Corrigir “Erro de estouro aritmético ao converter expressão em tipo de dados int” no SQL Server para corrigir isso.