Помилка арифметичного переповнення перетворення числового на числовий тип даних


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  

9
Я навіть не збираюся це
прибирати

3
Я перекинув ваш SQL через онлайн-форматор тут. dpriver.com/pp/sqlformat.htm Хоча все одно міг би зробити з ручним приведенням в порядок.
Martin Smith

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, і перевірити, чи вони більші, ніж може обробляти ваш стовпець.


17
Я не заважав би відповідати на запитання людей з автоматично створеними обліковими записами; вони не розуміють, де вони перебувають, і не повертаються, як тільки виправлять ситуацію. @ user572984: Привіт !? КОГО ДОМА? <taps screen> Ні, не думав.
Ola Tuvesson

Я зняв крапку з десяткового числа, тож вона стала більшою. Дякую!
Веллінгтон Лоріндо,

Перевірка Database field lengthдорівнює для того, щоб DataTableAdapterвідповідати довжині цього конкретного стовпця - Специфічний параметр збереженої процедури Довжина
Ельшан

1
@OlaTuvesson, на щастя, хоча User572984 є давнім і, ймовірно, ніколи цього не побачить, станом на сьогодні (8 жовтня 2020 р.) Його переглядали понад 270 тис. Разів! Отже, повернувши його UnknownUser, це виграло цілих 270 тис. Користувачів SO!
Ден

82

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

Надана відповідь ("Спробуйте десяткову (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
Шлях підвищення точності і залишаючи в масштабі те ж саме, ви є збільшенням кількості цифр перед десятковим. Тож те, що я сказав, не є неправильним, але я бачу, як це можна неправильно зрозуміти. Я сказав це так, оскільки ОП спочатку намагався вирішити проблему, просто збільшивши масштаб, але Ви маєте рацію; це повна точність, яку потрібно збільшити.
adam0101

1

Якщо ви хочете зменшити розмір до десяткового (7,2) з десяткового (9,2), вам доведеться враховувати наявні дані зі значеннями більшими, щоб вони вписувалися в десяткові (7,2). Або вам доведеться видалити ці номери, якщо їх скоротити, щоб вони відповідали вашому новому розміру. Якщо для поля, яке ви намагаєтесь оновити, не було даних, воно зробить це автоматично без проблем


0

Використовуйте функцію TRY_CAST точно так само, як функцію CAST. TRY_CAST бере рядок і намагається передати його типу даних, вказаному після ключового слова AS. Якщо перетворення не вдається, TRY_CAST повертає NULL замість того, щоб провалити.


1
TRY_CAST приймає вираз, значення якого відтворюється. Не просто струни, як ви це висловлюєте.
ТТ.

Хоча це дозволило б рутину завершити без помилок, це коштувало б втрачених даних. Метою помилки є вказати, що втручання потрібно для запобігання відсутнім даним. Ваше рішення буде працювати лише в тому випадку, якщо вам справді байдуже, наявний результат чи ні.
Ден

-2

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


OP вказує, що стовпець, про який йде мова, є числовим, а не цілим (як зазначено в повідомленні про помилку "Помилка арифметичного переповнення, перетворюючи числовий на числовий тип даних"), і відповідь, розміщена вгорі, правильно вирішує це. Ваша відповідь правильно визначає проблему (недостатньо місця для зберігання результату), але пропускає початковий намір питання.
Ден
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.