Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Corrige “Erro de estouro aritmético convertendo IDENTIDADE para tipo de dados…” no SQL Server


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.