Ошибка арифметического переполнения при преобразовании числового в числовой тип данных

88

Я получаю это сообщение об ошибке каждый раз, когда выполняю этот запрос:

Msg 8115, Level 16, State 8, Line 33
Arithmetic overflow error converting numeric to data type numeric.
The statement has been terminated.

Но если я изменю таблицу создания на (7,0), я не получу сообщения об ошибке, но мне нужно, чтобы мои данные отображались в виде десятичной дроби. Пробовал 8,3 не работает.

Есть ли кто-нибудь, кто может помочь мне в этом? Любая помощь будет принята с благодарностью.

DECLARE @StartDate AS DATETIME
DECLARE @StartDate_y AS DATETIME
DECLARE @EndDate AS DATETIME
DECLARE @temp_y AS DATETIME

SET @temp_y = Dateadd(yy, Datediff(yy, 0, Getdate()), 0)
SET @StartDate_y = Dateadd(dd, 1 - Datepart(dw, Dateadd("ww", -2, @temp_y)),
                                      Dateadd("ww", -2, @temp_y))
SET @StartDate = Dateadd(dd, 1 - Datepart(dw, Dateadd("ww", -2, Getdate())),
                                  Dateadd("ww", -2, Getdate()))
SET @EndDate = Dateadd(dd, 6, @StartDate)

--temp table to hold all cities in list
CREATE TABLE ##temp
  (
     city VARCHAR(50)
  )

INSERT INTO ##temp
VALUES     ('ABERDEEN'),
            ('CHESAPEAKE'),
            ('Preffered-Seafood/CHICAGO'),
            ('Preffered-Redist/CHICAGO'),
            ('CLACKAMAS'),
            ('COLUMBUS'),
            ('CONKLIN'),
            ('DENVER'),
            ('FORT WORTH'),
            ('HANOVER PARK'),
            ('JACKSONVILLE'),
            ('LAKELAND'),
            ('MONTGOMERY'),
            ('PFW-NORTHEAST'),
            ('PFW-SOUTHEAST'),
            ('RIVERSIDE'),
            ('TRENTON,CANADA'),
            ('VERNON')

--temp to hold data for the cities
CREATE TABLE #temp
  (
     city            VARCHAR(50),
     ytdshipments    INT,
     ytdtotalweight  DECIMAL(7, 2) NOT NULL,
     ytdtotalcharges DECIMAL (7, 2) NOT NULL
  --YTDRevperPound decimal (7,2) not null
  )

INSERT INTO #temp
SELECT ##temp.city,
       0,
       0,
       0
FROM   ##temp

INSERT #temp
-- YTD shipments/Charges/Weight by city
SELECT city = CASE
                WHEN nameaddrmstr_1.city IN( 'ABERDEEN', 'CHESAPEAKE', 'CHICAGO'
                                             ,
                                             'CLACKAMAS',
                                             'COLUMBUS', 'CONKLIN', 'DENVER',
                                             'FORT WORTH',
                                             'HANOVER PARK', 'JACKSONVILLE',
                                             'LAKELAND'
                                             ,
                                             'MONTGOMERY'
                                                    ,
                                             'RIVERSIDE', 'TRENTON', 'VERNON' )
              THEN
                CASE
                  WHEN
              nameaddrmstr_1.city = 'CHICAGO'
              AND h.shipr = 'PREFRESVS' THEN 'Preffered-Redist/CHICAGO'
                WHEN
              nameaddrmstr_1.city = 'TRENTON'
              AND nameaddrmstr_1.city = 'CA' THEN 'TRENTON,CANADA'
                ELSE
              nameaddrmstr_1.city
                END
                ELSE 'Other'
              END,
       ytdshipments = COUNT(CONVERT(VARCHAR(10), h.dateshipped, 101)),
       ytdtotalweight =SUM(CASE
                             WHEN h.totaldimwgt > h.totalwgt THEN h.totaldimwgt
                             ELSE h.totalwgt
                           END),
       ytdtotalcharges = SUM (cs.totalestrevcharges)
--YTDRevperPound = convert(decimal(7,2),sum (cs.TotalEstRevCharges )/sum( CASE WHEN h.TotalDimWGT > > h.TotalWGT THEN h.TotalDimWGT ELSE h.TotalWGT END ))
FROM   as400.dbo.hawb AS h WITH(nolock)
       INNER JOIN as400.dbo.chargesummary AS cs
         ON h.hawbnum = cs.hawbnum
       LEFT OUTER JOIN as400.dbo.nameaddrmstr AS nameaddrmstr_1
         ON h.shipr = nameaddrmstr_1.nameaddrcode
WHERE  h.dateshipped >= '01/01/2010'
       AND h.dateshipped <= '12/19/2010'
       --WHERE H.DateShipped >= >= @StartDate_y AND H.dateshipped <= @EndDate 
       AND h.cust IN( 'DARDENREED', 'MAINEDARDE', 'MBMRIVRSDE', 'MBMCOLUMBS',
                      'MBMLAKELND', 'MBMFTWORTH', 'SYGMACOLUM', 'SYGMANETW6',
                      'MAI215', 'MBMMNTGMRY' )
GROUP  BY CASE
  WHEN nameaddrmstr_1.city IN( 'ABERDEEN', 'CHESAPEAKE', 'CHICAGO', 'CLACKAMAS',
                               'COLUMBUS', 'CONKLIN', 'DENVER', 'FORT WORTH',
                               'HANOVER PARK', 'JACKSONVILLE', 'LAKELAND',
                               'MONTGOMERY'
                                      ,
                               'RIVERSIDE', 'TRENTON', 'VERNON' ) THEN CASE
                                                                         WHEN
nameaddrmstr_1.city = 'CHICAGO'
AND h.shipr = 'PREFRESVS' THEN 'Preffered-Redist/CHICAGO'
                                                                         WHEN
nameaddrmstr_1.city = 'TRENTON'
AND nameaddrmstr_1.city = 'CA' THEN 'TRENTON,CANADA'
                                                                         ELSE
nameaddrmstr_1.city
                                                                       END
  ELSE 'Other'
END

SELECT #temp.city                 AS city,
       MAX(#temp.ytdshipments)    AS ytdshipments,
       MAX(#temp.ytdtotalweight)  AS ytdtotalweight,
       MAX(#temp.ytdtotalcharges) AS ytdtotalcharges
FROM   #temp WITH(nolock)
       LEFT OUTER JOIN ##temp
         ON ##temp.city = #temp.city
GROUP  BY #temp.city

DROP TABLE #temp

DROP TABLE ##temp  
user572984
источник
9
Я даже не собираюсь начинать это
прибирать
3
Я забросил ваш SQL через онлайн-форматировщик здесь. dpriver.com/pp/sqlformat.htm Тем не менее, можно было бы провести ручную уборку .
Мартин Смит
3
почему не встроен форматер?
Адольф Чеснок
6
Microsoft, если вы слушаете, появляется сообщение об ошибке «Сообщение 8115, уровень 16, состояние 8, строка 1 Ошибка арифметического переполнения при преобразовании числового типа в числовой». можно улучшить, указав исходное значение, которое не удалось преобразовать. Это очень помогло бы при загрузке таблицы из 100 миллиардов строк и попытках понять, какое значение было нарушением. Снова было бы полезно добавить номер столбца в SELECT. НАПРИМЕР. ВЫБЕРИТЕ CAST (12345678910 как десятичное (12,0)), CAST (12345678910 как десятичное (12,2)) ... добавьте строку: «Значение: 12345678910 Столбец: 2» в сообщение об ошибке.
wwmbes

Ответы:

206

Я предполагаю, что вы пытаетесь втиснуть число больше 99999,99 в свои десятичные поля. Изменение его на (8,3) ничего не даст, если оно больше 99999.999 - вам нужно увеличить количество цифр перед десятичной дробью. Вы можете сделать это, увеличив точность (которая представляет собой общее количество цифр до и после десятичной дроби). Вы можете оставить шкалу без изменений, если вам не нужно изменять количество десятичных знаков для хранения. Попробуйте decimal(9,2)или decimal(10,2)или любой другой .

Вы можете проверить это, закомментировав insert #tempи посмотрев, какие числа дает вам оператор select, и посмотреть, больше ли они, чем может обработать ваш столбец.

adam0101
источник
17
Я бы не стал отвечать на вопросы людей с автоматически созданными аккаунтами; они не понимают, где они находятся, и не возвращаются после того, как поправились. @ user572984: ПРИВЕТ !? КТО-НИБУДЬ ДОМА? <тапает по экрану> Нет, не думаю.
Ola Tuvesson
Я убрал точку десятичного числа, поэтому оно стало больше. Благодарность!
Веллингтон Лориндо
Проверьте, Database field lengthравно ли DataTableAdapterэтому конкретному столбцу Длина - конкретный параметр хранимой процедуры Длина
Эльшан
1
@OlaTuvesson, к счастью, хотя User572984 длинный и, вероятно, никогда его не увидит, на сегодняшний день (8 октября 2020 г.) его просмотрели более 270 тысяч раз! Таким образом, выплатив его UnknownUser, оно принесло пользу 270 тысячам пользователей SO!
Дэн
83

Я чувствую, что мне нужно прояснить одну очень важную вещь для других (например, моего коллеги), которые наткнулись на эту ветку и получили неверную информацию.

Полученный ответ («Попробуйте десятичное (9,2) или десятичное (10,2) или что-то еще.») Правильный, но причина («увеличить количество цифр перед десятичным») неверна.

десятичное (p, s) и числовое (p, s) оба определяют точность и масштаб . «Точность» - это не количество цифр слева от десятичной дроби, а общая точность числа.

Например: десятичное (2,1) охватывает от 0,0 до 9,9, поскольку точность составляет 2 цифры (от 00 до 99), а масштаб равен 1. десятичное число (4,1) охватывает от 000,0 до 999,9, десятичное (4,2) охватывает от 00,00 до Десятичное число 99,99 (4,3) охватывает от 0,000 до 9,999

Дэн
источник
7
Путь повышения точности и оставляя в масштабе то же самое, вы являетесь увеличением количества цифр перед десятичным. То, что я сказал, не является неправильным, но я вижу, как это может быть неправильно понято. Я сказал это так, потому что OP изначально пытался решить проблему, просто увеличивая масштаб, но вы правы; необходимо повысить общую точность.
adam0101
1

Если вы хотите уменьшить размер до десятичного (7,2) с десятичного (9,2), вам придется учитывать существующие данные со значениями, большими, чтобы соответствовать десятичному (7,2). Либо вам придется удалить эти числа, либо усечь их, чтобы они соответствовали вашему новому размеру. Если не было данных для поля, которое вы пытаетесь обновить, оно сделает это автоматически без проблем.

Беной Джон
источник
0

Используйте функцию TRY_CAST точно так же, как функцию CAST. TRY_CAST принимает строку и пытается привести ее к типу данных, указанному после ключевого слова AS. Если преобразование не удается, TRY_CAST возвращает NULL вместо ошибки.

Бхарат
источник
1
TRY_CAST принимает выражение, значение которого приводится. Не просто струны, как вы это выразились.
ТТ.
Хотя это позволит выполнить процедуру без ошибок, это произойдет за счет отсутствия данных. Цель ошибки - указать, что требуется вмешательство для предотвращения пропуска данных. Ваше решение будет работать только в том случае, если вам действительно все равно, есть результат или нет.
Дан
-2

проверьте свое значение, которое вы хотите сохранить в целочисленном столбце. Я думаю, что это больше, чем диапазон целых чисел. если вы хотите сохранить значение больше целого диапазона. вы должны использовать тип данных bigint

Счастливый принц
источник
OP указывает, что рассматриваемый столбец является числовым, а не целочисленным (на что указывает сообщение об ошибке «Ошибка арифметического переполнения при преобразовании числового типа в числовой тип данных»), и в верхнем опубликованном ответе это правильно. Ваш ответ правильно определяет проблему (недостаточно места для хранения результата), но не отражает первоначальную цель вопроса.
Дан