sql >> Databasteknik >  >> RDS >> Sqlserver

Åtgärda "Aritmetiskt spillfel vid konvertering av IDENTITY till datatyp..." i SQL Server

Om du får felmeddelandet "Msg 8115, Level 16 Arithmetic overflow error converting IDENTITY till datatyp... ”-fel i SQL Server, beror det förmodligen på att du försöker infoga data i en tabell när dess IDENTITY kolumnen har nått sin datatyps gräns.

En IDENTITY kolumnen ökar automatiskt värdet som infogas med varje ny rad. Om värdet som infogas ligger utanför intervallet för kolumnens datatyp kommer ovanstående fel att uppstå.

Exempel på felet

Här är ett exempel på kod som resulterar i felet:

INSERT INTO t1 VALUES ('Dog');

Resultat:

Msg 8115, Level 16, State 1, Line 1
Arithmetic overflow error converting IDENTITY to data type tinyint.

I det här fallet, min IDENTITY kolumnen använder tinyint datatyp, som har ett intervall på 0 till 255. Felet innebär att IDENTITY kolumnen försöker infoga ett värde som är högre än 255.

Detta inträffar vanligtvis när vi redan har infogat 255 rader i kolumnen och nu försöker vi infoga den 256:e raden.

Så här ser min tabell ut när jag väljer alla rader med IDENTITY kolumnen är större än 250 :

SELECT * FROM t1
WHERE c1 > 250;

Resultat:

+------+------+
| c1   | c2   |
|------+------|
| 251  | Ant  |
| 252  | Cow  |
| 253  | Bat  |
| 254  | Duck |
| 255  | Bull |
+------+------+

I det här fallet, c1 är min IDENTITY kolumn (som råkar vara typ tinyint ). Vi kan se den IDENTITY har tidigare genererat 255 för kolumnen, så nästa värde som försöker infogas är 256 (förutsatt att ett ökningsvärde är 1 och inga tidigare misslyckade inlägg). Detta kommer att orsaka ovanstående fel, eftersom 256 är utanför intervallet för en tinyint .

Samma problem kan uppstå med datatyper av smallint (maximalt värde på 32 767) eller int (högsta värde av 2 147 483 647). Det kan också hända med bigint om du har infogat tillräckligt många rader (över 9 223 372 036 854 775 807).

Men IDENTITY värdet matchar inte alltid antalet infogade rader. Du kan ställa in ett startvärde när du skapar en IDENTITY kolumn, och du kan också ställa in ett inkrementvärde. Därför kan du lätt nå den övre gränsen mycket tidigare än antalet insättningar som utförs på bordet, beroende på frö- och inkrementvärden.

Att radera rader från en tabell återställer inte heller IDENTITY värde (även om trunkering av en tabell gör det).

Därför kan du fortfarande uppleva ovanstående fel även när det finns mycket färre rader i tabellen än vad IDENTITY kolumns datatyp kan föreslå.

Lösning

En lösning är att ändra datatypen för IDENTITY kolumn. Till exempel, om det är smallint , ändra den till int . Eller om det redan är int , ändra det till bigint .

En annan möjlig lösning skulle vara att återställa IDENTITY utsäde till ett lägre värde. Detta skulle bara fungera om du antingen har tagit bort många rader från tabellen eller om det ursprungliga startvärdet var mycket högre än 1 .

Till exempel, om IDENTITY kolumnen är redan en int , men IDENTITY seed började på säg 2,000,000,000 , kan du återställa IDENTITY seed till 1 , vilket skulle göra det möjligt för ytterligare 2 miljarder rader att infogas.

Användbara funktioner

Här är några funktioner som kan vara till stor hjälp för att identifiera det här problemet:

  • IDENT_CURRENT() – returnerar det senast genererade identitetsvärdet för en angiven tabell eller vy i en identitetskolumn.
  • @@IDENTITY – Returnerar det senast infogade identitetsvärdet i den aktuella sessionen.
  • IDENT_SEED() – Returnerar det ursprungliga fröet för en identitetskolumn.
  • IDENT_INCR() – Returnerar ökningsvärdet för en identitetskolumn.

Här är också tre sätt att få en kolumns datatyp om du inte är säker på vad kolumnens datatyp är.

Samma fel i olika scenarier

Samma fel (Msg 8115) kan också uppstå (med ett lite annorlunda felmeddelande) när du försöker explicit konvertera mellan datatyper och det ursprungliga värdet ligger utanför intervallet för den nya typen. Se Fixa "Arithmetic overflow-fel vid konvertering av int till datatyp numeric" i SQL Server för att åtgärda detta.

Det kan också inträffa när du använder en funktion som SUM() på en kolumn, och beräkningen resulterar i ett värde som ligger utanför intervallet för kolumntypen. Se Fixa "Arithmetic overflow-fel vid konvertering av uttryck till datatyp int" i SQL Server för att åtgärda detta.


  1. Lagring av binära datatyper i SQL Server

  2. Var finns PostgreSQL-loggarna på macOS?

  3. java.lang.ClassNotFoundException:org.postgresql.Driver, Android

  4. hur man använder Blob datatype i Postgres