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

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

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

但是如果我将 create 表更改为(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
364494 次浏览

我的猜测是,您试图将大于99999.99的数字压缩到小数字段中。如果它大于99999.999,将其改为(8,3)不会有任何作用-您需要增加小数位数 之前的数目。可以通过提高精度(即小数前后的总位数)来实现这一点。除非需要更改要存储的小数位数,否则可以保持刻度不变。试试 decimal(9,2)或者 decimal(10,2)什么的。

您可以通过注释掉 insert #temp来测试这一点,并查看 select 语句给出的数字,看看它们是否大于您的列能够处理的数字。

如果要将大小从十进制(9,2)减少到十进制(7,2) ,则必须考虑现有数据的大小,以适应十进制(7,2)。要么你将不得不删除这些数字是截断下来,以适应你的新大小。如果您试图更新的字段没有数据,那么它将自动更新,不会出现任何问题

我觉得我需要澄清一件非常重要的事情,对于其他人(比如我的同事)来说,他们看到了这个帖子却得到了错误的信息。

给出的答案(“试试十进制(9,2)或十进制(10,2)或其他。”)是正确的,但原因(“增加小数前的位数”)是错误的。

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

For example: 十进制(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

用与 CAST 函数完全相同的方法使用 TRY _ CAST 函数。TRY _ CAST 获取一个字符串,并尝试将其强制转换为在 AS 关键字之后指定的数据类型。如果转换失败,TRY _ CAST 返回 NULL 而不是失败。

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

(7,2)表示变量在小数点前面包含5位数字,在小数点后面包含2位数字。如果你把7位数放在小数前面,这是错误的。

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

我通过尝试隔离 select 语句来处理这些问题。

注释掉字段,直到可以隔离出实际问题所在的字段。

一旦您可以说: Select from

然后可以添加 Cast (字段为 numeric (4,6))[ tryMe ]

这样做的好处是选择 N 行,然后抛出错误。 然后可以取消强制转换,看看 N + 1的值是多少。

结果通常是令人惊讶的... ... 否则你不会读这么多!

I had a problem today where I was calculating tax and had Numeric(7,4) 最后的问题是我有一张欠税1000美元的订单。

Numeric(7,4) will only allow 3 digits to the left of the decimal. DOH!