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

问题描述 投票:0回答:7

每次运行此查询时,我都会收到此错误消息:

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  
sql sql-server-2008 type-conversion
7个回答
236
投票

我的猜测是,您正在尝试将大于 99999.99 的数字压缩到小数字段中。如果它大于 99999.999,则将其更改为 (8,3) 不会执行任何操作 - 您需要增加小数点之前的位数。您可以通过增加精度(即小数点前后的位数)来实现此目的。您可以保持比例不变,除非您需要更改要存储的小数位数。尝试 decimal(9,2)

decimal(10,2)
 或其他。

您可以通过注释掉

insert #temp

 来测试这一点,并查看 select 语句为您提供的数字,并查看它们是否大于您的列可以处理的大小。


124
投票
我觉得我需要为其他遇到此帖子并获得错误信息的人(例如我的同事)澄清一件非常重要的事情。

给出的答案(“尝试

decimal(9,2)

decimal(10,2)
或其他。”)是正确的,但原因(“增加小数点前的位数”)是错误的。

decimal(p,s)

numeric(p,s)
 都指定 
a Precision 和 Scale。 “精度”不是小数点左边的位数,而是数字的总精度。

例如:

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
 

decimal(4,3)
 涵盖 
0.000
9.999

    


3
投票
(7,2) 表示变量将包含小数点前 5 位数字和小数点后 2 位数字。如果您在小数点前输入 7 位数字,则错误。

为了更好地理解:-

https://www.sqlshack.com/understanding-sql-decimal-data-type/


2
投票
以与 CAST 函数完全相同的方式使用 TRY_CAST 函数。 TRY_CAST 接受一个字符串并尝试将其转换为 AS 关键字后指定的数据类型。如果转换失败,TRY_CAST 将返回 NULL 而不是失败。


1
投票
如果您想将大小从decimal(9,2)减小到decimal(7,2),则必须考虑现有数据的值更大以适合decimal(7,2)。您要么必须删除这些数字,要么将其截断以适合您的新尺寸。如果您尝试更新的字段没有数据,它将自动更新,不会出现任何问题


0
投票
我通过尝试隔离 select 语句来解决这些问题。

注释掉字段,直到您可以隔离哪个字段实际上是问题所在。

一旦您可以说:选择

然后您可以添加 Cast(field as numeric(4,6)) [tryMe]

这样做的好处是选择 N 行然后抛出错误。 然后你可以把石膏取下来看看 N+1 有什么值。

结果通常令人惊讶......否则你就不会读到这篇文章!

我今天遇到一个问题,我在计算税金时遇到了 Numeric(7,4) 问题最终是我有一个订单欠了 1000 美元的税。

Numeric(7,4) 只允许小数点左边 3 位数字。 卫生部!


-2
投票
检查要存储在整数列中的值。我认为这大于整数范围。如果你想存储大于整数范围的值。你应该使用bigint数据类型

© www.soinside.com 2019 - 2024. All rights reserved.