Ако получавате грешка „Съобщение 8115, Грешка при аритметично препълване на ниво 16 при преобразуване на IDENTITY в тип данни… ” грешка в SQL Server, вероятно защото се опитвате да вмъкнете данни в таблица, когато е IDENTITY
колоната е достигнала ограничението за типа данни.
IDENTITY
колона автоматично увеличава стойността, която се вмъква с всеки нов ред. Ако вмъкнатата стойност е извън обхвата на типа данни на колоната, тогава ще възникне горната грешка.
Пример за грешката
Ето пример за код, който води до грешката:
INSERT INTO t1 VALUES ('Dog');
Резултат:
Msg 8115, Level 16, State 1, Line 1 Arithmetic overflow error converting IDENTITY to data type tinyint.
В този случай моята IDENTITY
колоната използва tinyint
тип данни, който има диапазон от 0 до 255. Грешката предполага, че IDENTITY
колона се опитва да вмъкне стойност, която е по-висока от 255.
Това обикновено се случва, когато вече сме вмъкнали 255 реда в колоната и сега се опитваме да вмъкнем 256-ия ред.
Ето как изглежда моята таблица, когато избера всички редове, където IDENTITY
колоната е по-голяма от 250
:
SELECT * FROM t1
WHERE c1 > 250;
Резултат:
+------+------+ | c1 | c2 | |------+------| | 251 | Ant | | 252 | Cow | | 253 | Bat | | 254 | Duck | | 255 | Bull | +------+------+
В този случай c1
е моята IDENTITY
колона (която е тип tinyint
). Можем да видим това IDENTITY
преди това е генерирал 255
за колоната и така следващата стойност, която се опитва да вмъкне, е 256
(приемайки стойност на увеличение от 1
и без по-рано неуспешни вложки). Това ще причини горната грешка, тъй като 256 е извън обхвата на tinyint
.
Същият проблем може да възникне с типове данни smallint
(максимална стойност 32 767) или int
(максимална стойност от 2 147 483 647). Може да се случи и с bigint
ако сте вмъкнали достатъчно редове (над 9,223,372,036,854,775,807).
Въпреки това, IDENTITY
стойността не винаги съответства на броя на вмъкнатите редове. Можете да зададете начална стойност, когато създавате IDENTITY
колона и можете също да зададете стойност на увеличение. Следователно можете лесно да достигнете горната граница много по-рано от броя на вмъкванията, извършени на масата, в зависимост от стойностите на началната стойност и нарастването.
Също така, изтриването на редове от таблица не нулира IDENTITY
стойност (въпреки че съкращаването на таблица прави).
Следователно все още можете да изпитате горната грешка, дори когато има много по-малко редове в таблицата от това, което IDENTITY
типът данни на колоната може да предложи.
Решение
Едно решение е да промените типа данни на IDENTITY
колона. Например, ако е smallint
, променете го на int
. Или ако вече е int
, променете го на bigint
.
Друго възможно решение би било да нулирате IDENTITY
семена на по-ниска стойност. Това ще работи само ако или сте изтрили много редове от таблицата, или ако първоначалната начална стойност е много по-висока от 1
.
Например, ако IDENTITY
колоната вече е int
, но IDENTITY
семето започва от да речем 2,000,000,000
, можете да нулирате IDENTITY
начало на 1
, което ще позволи да бъдат вмъкнати още 2 милиарда реда.
Полезни функции
Ето някои функции, които могат да бъдат много полезни при идентифицирането на този проблем:
IDENT_CURRENT()
– връща последната генерирана стойност на идентичност за определена таблица или изглед в колона за идентичност.@@IDENTITY
– Връща последно въведената стойност на самоличността в текущата сесия.IDENT_SEED()
– Връща оригиналното начало на колона за идентичност.IDENT_INCR()
– Връща стойността на увеличение на колона за идентичност.
Също така, ето 3 начина да получите типа данни на колоната, в случай че не сте сигурни какъв е типът данни на колоната.
Една и съща грешка в различни сценарии
Същата грешка (Msg 8115) може да възникне (с малко по-различно съобщение за грешка), когато се опитате да преобразувате изрично между типове данни и оригиналната стойност е извън обхвата на новия тип. Вижте Коригиране на „Грешка при аритметично препълване при преобразуване int в числови тип данни“ в SQL Server, за да коригирате това.
Може да възникне и когато използвате функция като SUM()
върху колона и изчислението води до стойност, която е извън диапазона на типа на колоната. Вижте Коригиране на „Грешка при аритметично препълване при преобразуване на израз в тип данни int“ в SQL Server, за да коригирате това.