Lỗi tràn số học khi chuyển đổi số thành kiểu dữ liệu số


88

Tôi tiếp tục nhận được thông báo lỗi này mỗi khi tôi chạy truy vấn này:

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

Nhưng nếu tôi thay đổi bảng tạo thành (7,0), tôi không nhận được thông báo lỗi, nhưng tôi cần dữ liệu của mình được hiển thị dưới dạng số thập phân. Tôi đã thử 8,3 không hoạt động.

Có ai có thể giúp tôi làm việc này không? Mọi sự giúp đỡ sẽ được đánh giá rất cao.

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
Tôi thậm chí sẽ không bắt đầu thu dọn nó
m.edmondson

3
Tôi đã đánh lừa SQL của bạn thông qua trình định dạng trực tuyến ở đây. dpriver.com/pp/sqlformat.htm Tuy nhiên, vẫn có thể thực hiện với việc dọn dẹp thủ công.
Martin Smith

3
tại sao tùy chọn của một định dạng không được tích hợp sẵn?
tỏi Adolf

6
Microsoft, nếu bạn đang nghe, thông báo lỗi "Msg 8115, Mức 16, Trạng thái 8, Dòng 1 Lỗi tràn số học khi chuyển đổi số thành kiểu dữ liệu số." có thể được cải thiện bằng cách chỉ ra giá trị ban đầu không thể chuyển đổi. Điều đó sẽ giúp ích rất nhiều khi tải một bảng gồm 100 tỷ hàng và cố gắng hiểu giá trị nào đang vi phạm. Thêm số cột của một SELECT sẽ hữu ích trở lại. VÍ DỤ. CHỌN CAST (12345678910 dưới dạng thập phân (12,0)), CAST (12345678910 dưới dạng thập phân (12,2)) ... thêm chuỗi: "Giá trị: 12345678910 Cột: 2" vào thông báo lỗi.
wwmbes

Câu trả lời:


206

Tôi đoán là bạn đang cố ép một số lớn hơn 99999,99 vào các trường thập phân của mình. Thay đổi nó thành (8,3) sẽ không có tác dụng gì nếu nó lớn hơn 99999,999 - bạn cần phải tăng số chữ số trước số thập phân. Bạn có thể làm điều này bằng cách tăng độ chính xác (là tổng số chữ số trước và sau số thập phân). Bạn có thể giữ nguyên tỷ lệ trừ khi bạn cần thay đổi số lượng chữ số thập phân để lưu trữ. Hãy thử decimal(9,2)hoặc decimal(10,2)hoặc bất cứ điều gì.

Bạn có thể kiểm tra điều này bằng cách bình luận insert #tempvà xem câu lệnh select đang cho bạn những con số nào và xem chúng có lớn hơn cột của bạn có thể xử lý hay không.


17
Tôi sẽ không bận tâm trả lời câu hỏi từ những người có tài khoản được tạo tự động; họ không hiểu mình đang ở đâu và họ sẽ không quay lại sau khi đã sửa xong. @ user572984: HELLO !? NHÀ NÀO? <tap screen> Không, không nghĩ vậy.
Ola Tuvesson

Tôi đã bỏ dấu chấm của số thập phân, vì vậy nó lớn hơn. Cảm ơn!
Wellington Lorindo

Kiểm tra Database field lengthbằng để đến DataTableAdapterchiều dài mà cụ thể cột của - Stored Procedure của tham số cụ thể Chiều dài
Elshan

1
@OlaTuvesson, may mắn thay, mặc dù User572984 là một dài và có khả năng sẽ không bao giờ thấy điều này, tính đến ngày hôm nay (ngày 08 tháng 10 năm 2020) nó đã được xem Over 270K lần! Vì vậy, khi trả lại cho UnknownUser, nó đã được hưởng lợi từ 270 nghìn người dùng SO!
Dan

83

Tôi cảm thấy mình cần phải làm rõ một điều rất quan trọng, đối với những người khác (như đồng nghiệp của tôi), những người đã xem chuỗi này và nhận được thông tin sai.

Câu trả lời được đưa ra ("Hãy thử thập phân (9,2) hoặc thập phân (10,2) hoặc bất cứ thứ gì.") Là đúng, nhưng lý do ("tăng số chữ số trước số thập phân") là sai.

thập phân (p, s) và số (p, s) đều chỉ định Độ chính xác và Tỷ lệ . "Độ chính xác" không phải là số chữ số ở bên trái của số thập phân, mà thay vào đó là tổng độ chính xác của số.

Ví dụ: số thập phân (2,1) bao gồm từ 0,0 đến 9,9, vì độ chính xác là 2 chữ số (00 đến 99) và tỷ lệ là 1. số thập phân (4,1) bao gồm 000.0 đến 999,9 phần thập phân (4,2) bao gồm 00,00 thành 99,99 thập phân (4,3) bao gồm 0,000 đến 9,999


7
Bằng cách tăng độ chính xác và giữ nguyên tỷ lệ, bạn đang tăng số chữ số trước số thập phân. Vì vậy, những gì tôi nói không sai, nhưng tôi thấy nó có thể bị hiểu lầm như thế nào. Tôi đã nói như vậy bởi vì OP ban đầu đang cố gắng khắc phục sự cố bằng cách tăng quy mô, nhưng bạn đã đúng; đó là tổng độ chính xác cần được tăng lên.
adam0101

1

Nếu bạn muốn giảm kích thước thành số thập phân (7,2) từ số thập phân (9,2), bạn sẽ phải tính đến dữ liệu hiện có với các giá trị lớn hơn để vừa với số thập phân (7,2). Hoặc bạn sẽ phải xóa những con số đó là cắt bớt nó để vừa với kích thước mới của bạn. Nếu không có dữ liệu cho trường bạn đang cố gắng cập nhật, nó sẽ tự động làm việc đó mà không có vấn đề gì


0

Sử dụng hàm TRY_CAST theo cách chính xác của hàm CAST. TRY_CAST nhận một chuỗi và cố gắng truyền nó sang kiểu dữ liệu được chỉ định sau từ khóa AS. Nếu chuyển đổi không thành công, TRY_CAST trả về NULL thay vì không thành công.


1
TRY_CAST nhận một biểu thức, giá trị của nó được ép kiểu. Không chỉ là chuỗi như bạn đặt nó.
TT.

Mặc dù điều đó sẽ cho phép quy trình hoàn thành mà không có lỗi, nhưng nó sẽ phải trả giá bằng việc thiếu dữ liệu. Mục đích của lỗi là để chỉ ra rằng cần có sự can thiệp để ngăn chặn dữ liệu bị thiếu. Giải pháp của bạn sẽ chỉ hoạt động nếu bạn thực sự không quan tâm nếu kết quả hiện tại hay không.
Dan

-2

kiểm tra giá trị mà bạn muốn lưu trữ trong cột số nguyên. Tôi nghĩ rằng đây là phạm vi số nguyên lớn hơn. nếu bạn muốn lưu trữ giá trị lớn hơn thì phạm vi số nguyên. bạn nên sử dụng kiểu dữ liệu bigint


OP chỉ ra rằng cột được đề cập là Số chứ không phải Số nguyên (như được chỉ ra bởi thông báo lỗi "Lỗi tràn số học khi chuyển đổi số thành kiểu dữ liệu số.") Và câu trả lời được đăng trên cùng giải quyết chính xác vấn đề này. Câu trả lời của bạn xác định chính xác vấn đề (không đủ chỗ để lưu kết quả) nhưng lại bỏ sót ý định ban đầu của câu hỏi.
Dan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.