Si vous obtenez l'erreur "Msg 8115, Erreur de débordement arithmétique de niveau 16 lors de la conversion de IDENTITY en type de données… ” dans SQL Server, c'est probablement parce que vous essayez d'insérer des données dans une table alors que son IDENTITY
la colonne a atteint la limite de son type de données.
Une IDENTITY
La colonne incrémente automatiquement la valeur insérée à chaque nouvelle ligne. Si la valeur insérée est hors de la plage du type de données de la colonne, l'erreur ci-dessus se produira.
Exemple d'erreur
Voici un exemple de code qui génère l'erreur :
INSERT INTO t1 VALUES ('Dog');
Résultat :
Msg 8115, Level 16, State 1, Line 1 Arithmetic overflow error converting IDENTITY to data type tinyint.
Dans ce cas, mon IDENTITY
la colonne utilise le tinyint
type de données, qui a une plage de 0 à 255. L'erreur implique que le IDENTITY
la colonne essaie d'insérer une valeur supérieure à 255.
Cela se produit généralement lorsque nous avons déjà inséré 255 lignes dans la colonne et que nous essayons maintenant d'insérer la 256e ligne.
Voici à quoi ressemble ma table lorsque je sélectionne toutes les lignes où le IDENTITY
la colonne est supérieure à 250
:
SELECT * FROM t1
WHERE c1 > 250;
Résultat :
+------+------+ | c1 | c2 | |------+------| | 251 | Ant | | 252 | Cow | | 253 | Bat | | 254 | Duck | | 255 | Bull | +------+------+
Dans ce cas, c1
est mon IDENTITY
colonne (qui se trouve être de type tinyint
). Nous pouvons voir que IDENTITY
a déjà généré 255
pour la colonne, et donc la prochaine valeur qui essaie d'insérer est 256
(en supposant une valeur d'incrément de 1
et aucune insertion précédemment échouée). Cela provoquera l'erreur ci-dessus, car 256 est en dehors de la plage d'un tinyint
.
Le même problème peut se produire avec les types de données smallint
(valeur maximale de 32 767) ou int
(valeur maximale de 2 147 483 647). Cela peut aussi arriver avec bigint
si vous avez inséré suffisamment de lignes (plus de 9 223 372 036 854 775 807).
Cependant, l'IDENTITY
la valeur ne correspond pas toujours au nombre de lignes insérées. Vous pouvez définir une valeur de départ lors de la création d'un IDENTITY
colonne, et vous pouvez également définir une valeur d'incrément. Par conséquent, vous pouvez facilement atteindre la limite supérieure bien avant le nombre d'insertions effectuées sur la table, en fonction des valeurs de départ et d'incrément.
De plus, la suppression de lignes d'une table ne réinitialise pas l'IDENTITY
valeur (bien que tronquer une table le fasse).
Par conséquent, vous pouvez toujours rencontrer l'erreur ci-dessus même s'il y a beaucoup moins de lignes dans la table que ce que le IDENTITY
le type de données de la colonne pourrait suggérer.
Solution
Une solution consiste à changer le type de données de IDENTITY
colonne. Par exemple, si c'est smallint
, changez-le en int
. Ou si c'est déjà int
, remplacez-le par bigint
.
Une autre solution possible serait de réinitialiser le IDENTITY
graine à une valeur inférieure. Cela ne fonctionnerait que si vous avez supprimé un grand nombre de lignes de la table ou si la valeur de départ d'origine était bien supérieure à 1
.
Par exemple, si le IDENTITY
la colonne est déjà un int
, mais l'IDENTITY
la graine a commencé à dire 2,000,000,000
, vous pouvez réinitialiser l'IDENTITY
graine à 1
, ce qui permettrait d'insérer 2 milliards de lignes supplémentaires.
Fonctions utiles
Voici quelques fonctions qui peuvent être très utiles pour identifier ce problème :
IDENT_CURRENT()
– renvoie la dernière valeur d'identité générée pour une table ou une vue spécifiée sur une colonne d'identité.@@IDENTITY
– Renvoie la dernière valeur d'identité insérée dans la session en cours.IDENT_SEED()
– Renvoie la graine d'origine d'une colonne d'identité.IDENT_INCR()
– Renvoie la valeur d'incrément d'une colonne d'identité.
Voici également 3 façons d'obtenir le type de données d'une colonne au cas où vous n'êtes pas sûr du type de données de la colonne.
Même erreur dans différents scénarios
La même erreur (Msg 8115) peut également se produire (avec un message d'erreur légèrement différent) lorsque vous essayez de convertir explicitement entre les types de données et que la valeur d'origine est en dehors de la plage du nouveau type. Voir Corriger "Erreur de débordement arithmétique lors de la conversion de int en type de données numérique" dans SQL Server pour résoudre ce problème.
Cela peut également se produire lorsque vous utilisez une fonction telle que SUM()
sur une colonne, et le calcul donne une valeur en dehors de la plage du type de colonne. Voir Corriger "Erreur de débordement arithmétique lors de la conversion de l'expression en type de données int" dans SQL Server pour résoudre ce problème.