Hvis du får fejlmeddelelsen "Msg 8115, niveau 16 aritmetisk overløbsfejl ved konvertering af IDENTITY til datatype... ” fejl i SQL Server, er det sandsynligvis fordi du forsøger at indsætte data i en tabel, når dens IDENTITY
kolonnen har nået sin datatypegrænse.
En IDENTITY
kolonne øger automatisk den værdi, der er indsat med hver ny række. Hvis værdien, der indsættes, er uden for området for kolonnens datatype, vil ovenstående fejl opstå.
Eksempel på fejlen
Her er et eksempel på kode, der resulterer i fejlen:
INSERT INTO t1 VALUES ('Dog');
Resultat:
Msg 8115, Level 16, State 1, Line 1 Arithmetic overflow error converting IDENTITY to data type tinyint.
I dette tilfælde er min IDENTITY
kolonnen bruger tinyint
datatype, som har et interval på 0 til 255. Fejlen antyder, at IDENTITY
kolonnen forsøger at indsætte en værdi, der er højere end 255.
Dette vil typisk ske, når vi allerede har indsat 255 rækker i kolonnen, og nu forsøger vi at indsætte den 256. række.
Sådan ser min tabel ud, når jeg vælger alle rækker med IDENTITY
kolonne er større end 250
:
SELECT * FROM t1
WHERE c1 > 250;
Resultat:
+------+------+ | c1 | c2 | |------+------| | 251 | Ant | | 252 | Cow | | 253 | Bat | | 254 | Duck | | 255 | Bull | +------+------+
I dette tilfælde c1
er min IDENTITY
kolonne (som tilfældigvis er typen tinyint
). Vi kan se den IDENTITY
har tidligere genereret 255
for kolonnen, og så er den næste værdi, der forsøger at indsætte, 256
(forudsat en stigningsværdi på 1
og ingen tidligere mislykkede indsatser). Dette vil forårsage ovenstående fejl, fordi 256 er uden for området for en tinyint
.
Det samme problem kan opstå med datatyper af smallint
(maksimal værdi på 32.767) eller int
(maksimal værdi af 2.147.483.647). Det kan også ske med bigint
hvis du har indsat nok rækker (over 9.223.372.036.854.775.807).
Men IDENTITY
værdien matcher ikke altid antallet af indsatte rækker. Du kan indstille en startværdi, når du opretter en IDENTITY
kolonne, og du kan også indstille en stigningsværdi. Derfor kan du nemt nå den øvre grænse meget tidligere end antallet af indsatser, der udføres på bordet, afhængigt af frø- og stigningsværdierne.
Sletning af rækker fra en tabel nulstiller heller ikke IDENTITY
værdi (selvom afkortning af en tabel gør).
Derfor kan du stadig opleve ovenstående fejl, selv når der er langt færre rækker i tabellen end IDENTITY
kolonnens datatype kan foreslå.
Løsning
En løsning er at ændre datatypen for IDENTITY
kolonne. For eksempel, hvis det er smallint
, ændre det til int
. Eller hvis det allerede er int
, ændre det til bigint
.
En anden mulig løsning ville være at nulstille IDENTITY
frø til en lavere værdi. Dette ville kun fungere, hvis du enten har slettet mange rækker fra tabellen, eller hvis den oprindelige startværdi var meget højere end 1
.
For eksempel, hvis IDENTITY
kolonne er allerede en int
, men IDENTITY
frø startede ved sige 2,000,000,000
, kan du nulstille IDENTITY
frø til 1
, hvilket ville give mulighed for at indsætte yderligere 2 milliarder rækker.
Nyttige funktioner
Her er nogle funktioner, der kan være meget nyttige til at identificere dette problem:
IDENT_CURRENT()
– returnerer den sidst genererede identitetsværdi for en specificeret tabel eller visning på en identitetskolonne.@@IDENTITY
– Returnerer den sidst indsatte identitetsværdi i den aktuelle session.IDENT_SEED()
– Returnerer det oprindelige frø af en identitetskolonne.IDENT_INCR()
– Returnerer den øgede værdi af en identitetskolonne.
Her er også 3 måder at få en kolonnes datatype på, hvis du ikke er sikker på, hvad kolonnens datatype er.
Samme fejl i forskellige scenarier
Den samme fejl (Msg 8115) kan også opstå (med en lidt anderledes fejlmeddelelse), når du forsøger eksplicit at konvertere mellem datatyper, og den oprindelige værdi er uden for rækkevidden af den nye type. Se Ret "Aritmetisk overløbsfejl ved konvertering af int til datatype numerisk" i SQL Server for at rette dette.
Det kan også forekomme, når du bruger en funktion såsom SUM()
på en kolonne, og beregningen resulterer i en værdi, der ligger uden for rækkevidden af kolonnens type. Se Ret "Aritmetisk overløbsfejl ved konvertering af udtryk til datatype int" i SQL Server for at rette dette.