[sql] 숫자를 숫자 데이터 유형으로 변환하는 산술 오버플로 오류

이 쿼리를 실행할 때마다이 오류 메시지가 계속 표시됩니다.

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

그러나 테이블 생성을 (7,0)으로 변경하면 오류 메시지가 나타나지 않지만 데이터를 10 진수로 표시해야합니다. 나는 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  



답변

내 생각에는 99999.99보다 큰 숫자를 소수 필드에 집어 넣으려는 것입니다. 99999.999보다 크면 (8,3)으로 변경해도 아무 작업도 수행되지 않습니다 . 소수점 의 자릿수를 늘려야합니다 . 정밀도 (소수점 앞뒤의 총 자릿수)를 증가시켜이를 수행 할 수 있습니다. 저장할 소수 자릿수를 변경할 필요가없는 한 스케일을 그대로 둘 수 있습니다. 시도 decimal(9,2)하거나 decimal(10,2)또는 무엇이든.

주석을 달아서 이것을 테스트 insert #temp하고 select 문이 제공하는 숫자를 확인하고 열이 처리 할 수있는 것보다 큰지 확인할 수 있습니다.


답변

이 스레드를 발견하고 잘못된 정보를 얻은 다른 사람 (예 : 동료)을 위해 매우 중요한 한 가지를 명확히해야한다고 생각합니다.

주어진 대답 ( “Try decimal (9,2) 또는 decimal (10,2) 또는 무엇이든.”)은 정확하지만 이유 ( “소수점 앞의 자릿수 늘리기”)는 잘못되었습니다.

decimal (p, s) 및 numeric (p, s) 모두 Precision 및 Scale을 지정 합니다 . “정밀도”는 소수점 왼쪽에있는 자릿수가 아니라 숫자의 총 정밀도입니다.

예 : decimal (2,1)은 정밀도가 2 자리 (00 ~ 99)이고 스케일이 1이기 때문에 0.0 ~ 9.9를 포함합니다. decimal (4,1)은 000.0 ~ 999.9를 포함합니다. decimal (4,2)는 00.00 ~를 포함합니다. 99.99 십진수 (4,3)는 0.000 ~ 9.999를 포함합니다.


답변

크기를 decimal (9,2)에서 decimal (7,2)로 줄이려면 decimal (7,2)에 맞도록 더 큰 값을 가진 기존 데이터를 고려해야합니다. 해당 번호를 삭제해야 새 크기에 맞게 잘립니다. 업데이트하려는 필드에 대한 데이터가 없으면 문제없이 자동으로 수행됩니다.


답변

CAST 함수와 똑같은 방식으로 TRY_CAST 함수를 사용합니다. TRY_CAST는 문자열을 가져 와서 AS 키워드 뒤에 지정된 데이터 유형으로 캐스트하려고합니다. 변환이 실패하면 TRY_CAST는 실패하는 대신 NULL을 반환합니다.


답변

정수 열에 저장하려는 값을 확인하십시오. 나는 이것이 정수 범위보다 크다고 생각합니다. 정수 범위보다 큰 값을 저장하려는 경우. bigint 데이터 유형을 사용해야합니다.


답변