简体   繁体   English

将数字转换为数据类型数字的算术溢出错误

[英]Arithmetic overflow error converting numeric to data type numeric

I keep getting this error message everytime I run this query:每次运行此查询时,我都会收到此错误消息:

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

But if I change the create table to (7,0), I don't get the error message.But I need my data to be displayed as a decimal.但是,如果我将创建表更改为 (7,0),则不会收到错误消息。但我需要将我的数据显示为小数。 I have tried 8,3 does not work.我试过8,3不行。

Is there any one who can help me work this?Any help will be greatly appreciated.有没有人可以帮助我解决这个问题?任何帮助将不胜感激。

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  

My guess is that you're trying to squeeze a number greater than 99999.99 into your decimal fields.我的猜测是您试图将大于 99999.99 的数字压缩到您的十进制字段中。 Changing it to (8,3) isn't going to do anything if it's greater than 99999.999 - you need to increase the number of digits before the decimal.如果它大于 99999.999,将其更改为 (8,3) 不会做任何事情 - 您需要增加小数点的位数。 You can do this by increasing the precision (which is the total number of digits before and after the decimal).您可以通过提高精度(即小数点前后的总位数)来实现这一点。 You can leave the scale the same unless you need to alter how many decimal places to store.除非您需要更改要存储的小数位数,否则您可以保持比例不变。 Try decimal(9,2) or decimal(10,2) or whatever.尝试decimal(9,2)decimal(10,2)或其他什么。

You can test this by commenting out the insert #temp and see what numbers the select statement is giving you and see if they are bigger than your column can handle.您可以通过注释掉insert #temp来测试这一点,并查看 select 语句给您的数字,并查看它们是否大于您的列可以处理的数字。

I feel I need to clarify one very important thing, for others (like my co-worker) who came across this thread and got the wrong information.我觉得我需要澄清一件非常重要的事情,对于遇到此线程并获得错误信息的其他人(例如我的同事)。

The answer given ("Try decimal(9,2) or decimal(10,2) or whatever.") is correct, but the reason ("increase the number of digits before the decimal") is wrong.给出的答案(“尝试十进制(9,2)或十进制(10,2)或其他。”)是正确的,但原因(“增加小数点前的位数”)是错误的。

decimal(p,s) and numeric(p,s) both specify a Precision and a Scale . decimal(p,s) 和 numeric(p,s) 都指定Precision 和 Scale The "precision" is not the number of digits to the left of the decimal, but instead is the total precision of the number. “精度”不是小数点左边的位数,而是数字的总精度。

For example: decimal(2,1) covers 0.0 to 9.9, because the precision is 2 digits (00 to 99) and the scale is 1. decimal(4,1) covers 000.0 to 999.9 decimal(4,2) covers 00.00 to 99.99 decimal(4,3) covers 0.000 to 9.999例如:decimal(2,1)覆盖0.0到9.9,因为精度是2位(00到99),小数位数是1。decimal(4,1)覆盖000.0到999.9 decimal(4,2)覆盖00.00到99.99 十进制 (4,3) 涵盖 0.000 到 9.999

If you want to reduce the size to decimal(7,2) from decimal(9,2) you will have to account for the existing data with values greater to fit into decimal(7,2).如果要将大小从小数 (9,2) 减小到小数 (7,2),则必须考虑具有更大值以适合小数 (7,2) 的现有数据。 Either you will have to delete those numbers are truncate it down to fit into your new size.您要么必须删除这些数字,要么将其截断以适应您的新尺寸。 If there was no data for the field you are trying to update it will do it automatically without issues如果您尝试更新的字段没有数据,它将自动执行而不会出现问题

(7,2) it means, variable will contain 5 digits before the decimal and 2 digits after decimal .if you are putting 7 digits before the decimal that is wrong. (7,2) 这意味着,变量将包含小数点前 5 位数字和小数点后 2 位数字。如果您在小数点前放置 7 位数字是错误的。

for better understand :- https://www.sqlshack.com/understanding-sql-decimal-data-type/为了更好地理解:- https://www.sqlshack.com/understanding-sql-decimal-data-type/

Use TRY_CAST function in exact same way of CAST function.以与 CAST 函数完全相同的方式使用 TRY_CAST 函数。 TRY_CAST takes a string and tries to cast it to a data type specified after the AS keyword. TRY_CAST 接受一个字符串并尝试将其强制转换为在 AS 关键字之后指定的数据类型。 If the conversion fails, TRY_CAST returns a NULL instead of failing.如果转换失败,TRY_CAST 将返回 NULL 而不是失败。

I approach these problems by trying to isolate the select statement.我通过尝试隔离 select 语句来解决这些问题。

Comment out fields until you can isolate which field is actually the problem.注释掉字段,直到您可以确定哪个字段实际上是问题。

Once you can say : Select from一旦你可以说:从

you can then add Cast(field as numeric(4,6)) [tryMe]然后你可以添加 Cast(field as numeric(4,6)) [tryMe]

This has the benefit of selecting N rows and then throwing the error.这具有选择 N 行然后抛出错误的好处。 You can then take the cast off and see what value N+1 has.然后,您可以去掉演员表,看看 N+1 有什么价值。

The result is usually surprising... or you would not be reading this SO!结果通常是令人惊讶的……否则你就不会读这个了!

I had a problem today where I was calculating tax and had Numeric(7,4) The issue wound up being I had one order that owed 1000$ in tax.我今天在计算税款时遇到了一个问题,并且有 Numeric(7,4) 问题最终是我有一个欠税 1000 美元的订单。

Numeric(7,4) will only allow 3 digits to the left of the decimal. Numeric(7,4) 只允许小数点左边的 3 位数字。 DOH!哦!

check your value which you want to store in integer column.检查要存储在整数列中的值。 I think this is greater then range of integer.我认为这大于整数范围。 if you want to store value greater then integer range.如果你想存储大于整数范围的值。 you should use bigint datatype你应该使用 bigint 数据类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM