Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Risolto il problema con "Errore di overflow aritmetico durante la conversione dell'IDENTITÀ in tipo di dati..." in SQL Server

Se ricevi l'errore "Msg 8115, errore di overflow aritmetico di livello 16 durante la conversione di IDENTITY in tipo di dati... ” errore in SQL Server, probabilmente è perché stai cercando di inserire dati in una tabella quando è IDENTITY colonna ha raggiunto il limite del tipo di dati.

Un IDENTITY colonna incrementa automaticamente il valore inserito con ogni nuova riga. Se il valore inserito non rientra nell'intervallo del tipo di dati della colonna, si verificherà l'errore precedente.

Esempio di errore

Ecco un esempio di codice che genera l'errore:

INSERT INTO t1 VALUES ('Dog');

Risultato:

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

In questo caso, il mio IDENTITY la colonna utilizza tinyint tipo di dati, che ha un intervallo compreso tra 0 e 255. L'errore implica che IDENTITY la colonna sta tentando di inserire un valore maggiore di 255.

Ciò si verifica in genere quando abbiamo già inserito 255 righe nella colonna e ora stiamo cercando di inserire la 256a riga.

Ecco come appare la mia tabella quando seleziono tutte le righe in cui è IDENTITY la colonna è maggiore di 250 :

SELECT * FROM t1
WHERE c1 > 250;

Risultato:

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

In questo caso, c1 è la mia IDENTITY colonna (che sembra essere di tipo tinyint ). Possiamo vedere che IDENTITY ha precedentemente generato 255 per la colonna, quindi il valore successivo che tenta di inserire è 256 (assumendo un valore di incremento di 1 e nessun inserimento precedentemente fallito). Ciò causerà l'errore precedente, perché 256 non rientra nell'intervallo di un tinyint .

Lo stesso problema può verificarsi con i tipi di dati di smallint (valore massimo 32.767) o int (valore massimo di 2.147.483.647). Potrebbe succedere anche con bigint se hai inserito abbastanza righe (oltre 9.223.372.036.854.775.807).

Tuttavia, l'IDENTITY il valore non sempre corrisponde al numero di righe inserite. Puoi impostare un valore seed quando crei un IDENTITY colonna e puoi anche impostare un valore di incremento. Pertanto, potresti facilmente raggiungere il limite superiore molto prima del numero di inserti eseguiti sulla tavola, a seconda del seme e dei valori di incremento.

Inoltre, l'eliminazione di righe da una tabella non reimposta IDENTITY value (sebbene il troncamento di una tabella lo faccia).

Pertanto, potresti comunque riscontrare l'errore precedente anche quando ci sono molte meno righe nella tabella rispetto a IDENTITY il tipo di dati della colonna potrebbe suggerire.

Soluzione

Una soluzione è cambiare il tipo di dati di IDENTITY colonna. Ad esempio, se è smallint , cambialo in int . O se è già int , cambialo in bigint .

Un'altra possibile soluzione sarebbe reimpostare IDENTITY seme a un valore inferiore. Funzionerebbe solo se hai eliminato molte righe dalla tabella o se il valore del seme originale era molto superiore a 1 .

Ad esempio, se il IDENTITY la colonna è già un int , ma l'IDENTITY il seme è iniziato a dire 2,000,000,000 , potresti reimpostare IDENTITY invia a 1 , che consentirebbe di inserire altri 2 miliardi di righe.

Funzioni utili

Ecco alcune funzioni che possono essere molto utili per identificare questo problema:

  • IDENT_CURRENT() – restituisce l'ultimo valore di identità generato per una tabella o una vista specificata su una colonna di identità.
  • @@IDENTITY – Restituisce l'ultimo valore di identità inserito nella sessione corrente.
  • IDENT_SEED() – Restituisce il seme originale di una colonna di identità.
  • IDENT_INCR() – Restituisce il valore di incremento di una colonna Identity.

Inoltre, ecco 3 modi per ottenere il tipo di dati di una colonna nel caso in cui non sei sicuro di quale sia il tipo di dati della colonna.

Stesso errore in diversi scenari

Lo stesso errore (Msg 8115) può verificarsi anche (con un messaggio di errore leggermente diverso) quando si tenta di convertire in modo esplicito tra tipi di dati e il valore originale non rientra nell'intervallo del nuovo tipo. Per risolvere questo problema, vedere Correzione "Errore di overflow aritmetico durante la conversione int in tipo di dati numerico" in SQL Server.

Può verificarsi anche quando si utilizza una funzione come SUM() su una colonna e il calcolo restituisce un valore che non rientra nell'intervallo del tipo di colonna. Per risolvere il problema, vedere "Errore di overflow aritmetico durante la conversione dell'espressione in tipo di dati int" in SQL Server.