Kesalahan overflow aritmatika yang mengonversi numerik menjadi tipe data numerik

91

Saya terus mendapatkan pesan kesalahan ini setiap kali saya menjalankan kueri ini:

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

Tetapi jika saya mengubah buat tabel menjadi (7,0), saya tidak mendapatkan pesan kesalahan, tetapi saya ingin data saya ditampilkan sebagai desimal. Saya sudah mencoba 8,3 tidak berhasil.

Apakah ada orang yang dapat membantu saya mengerjakan ini? Bantuan apa pun akan sangat dihargai.

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  
pengguna572984
sumber
11
Saya bahkan tidak akan mulai merapikannya
m.edmondson
4
Saya membuang SQL Anda melalui pemformat online di sini. dpriver.com/pp/sqlformat.htm Masih bisa dilakukan dengan merapikan manual.
Martin Smith
3
mengapa opsi formatter tidak ada di dalamnya?
adolf bawang putih
12
Microsoft, jika Anda mendengarkan, pesan kesalahan "Msg 8115, Level 16, Negara 8, Baris 1 Kesalahan aritmatika overflow mengonversi numerik ke tipe data numerik." dapat ditingkatkan dengan menunjukkan nilai asli yang tidak dapat dikonversi. Itu akan sangat membantu saat memuat tabel 100 miliar baris dan mencoba memahami nilai mana yang menyinggung. Menambahkan nomor kolom dari sebuah SELECT akan berguna lagi. MISALNYA. PILIH CAST (12345678910 sebagai desimal (12,0)), CAST (12345678910 sebagai desimal (12,2)) ... tambahkan string: "Value: 12345678910 Column: 2" ke pesan kesalahan.
wwmbes

Jawaban:

208

Tebakan saya adalah Anda mencoba memasukkan angka yang lebih besar dari 99999,99 ke dalam bidang desimal Anda. Mengubahnya menjadi (8,3) tidak akan menghasilkan apa-apa jika lebih besar dari 99999.999 - Anda perlu menambah jumlah digit sebelum desimal. Anda dapat melakukan ini dengan meningkatkan presisi (yaitu jumlah total digit sebelum dan sesudah desimal). Anda dapat membiarkan skala tetap sama kecuali Anda perlu mengubah berapa banyak tempat desimal untuk disimpan. Coba decimal(9,2)atau decimal(10,2)atau apa pun.

Anda dapat mengujinya dengan mengomentari insert #tempdan melihat angka apa yang diberikan pernyataan pilih kepada Anda dan melihat apakah angka tersebut lebih besar dari yang dapat ditangani kolom Anda.

adam0101
sumber
18
Saya tidak akan repot-repot menjawab pertanyaan dari orang-orang dengan akun yang dibuat secara otomatis; mereka tidak mengerti di mana mereka berada dan mereka tidak kembali setelah mereka memperbaikinya. @ user572984: HALO !? ADA ORANG DIRUMAH? <Taps screen> Tidak, sepertinya tidak.
Ola Tuvesson
Saya telah menghilangkan titik dari angka desimal, jadi semakin besar. Terima kasih!
Wellington Lorindo
Periksa Database field lengthsama dengan untuk DataTableAdapterPanjang kolom spesifik itu - Panjang parameter spesifik Prosedur Tersimpan
Elshan
3
@OlaTuvesson, untungnya, meskipun User572984 panjang dan kemungkinan besar tidak akan pernah melihatnya, sampai hari ini (8 Okt 2020) telah dilihat Lebih dari 270K Kali! Jadi, dalam membayarnya kembali ke UnknownUser, itu menguntungkan sebanyak 270 ribu pengguna SO!
Dan
85

Saya merasa saya perlu mengklarifikasi satu hal yang sangat penting, untuk orang lain (seperti rekan kerja saya) yang menemukan utas ini dan mendapatkan informasi yang salah.

Jawaban yang diberikan ("Coba desimal (9,2) atau desimal (10,2) atau apapun.") Benar, tetapi alasannya ("tambah jumlah digit sebelum desimal") salah.

desimal (p, s) dan numerik (p, s) keduanya menentukan Presisi dan Skala . "Presisi" bukanlah jumlah digit di sebelah kiri desimal, melainkan presisi total dari angka tersebut.

Contoh: desimal (2,1) mencakup 0,0 hingga 9,9, karena presisi adalah 2 digit (00 hingga 99) dan skala 1. desimal (4,1) mencakup 000,0 hingga 999,9 desimal (4,2) mencakup 00.00 hingga 99,99 desimal (4,3) mencakup 0,000 hingga 9,999

Dan
sumber
7
Dengan meningkatkan presisi dan meninggalkan skala yang sama, Anda akan meningkatkan jumlah digit sebelum desimal. Jadi apa yang saya katakan tidak salah, tapi saya melihat bagaimana itu bisa disalahpahami. Saya mengatakannya seperti itu karena OP pada awalnya mencoba untuk memperbaiki masalah hanya dengan meningkatkan skala, tetapi Anda benar; presisi totallah yang perlu ditingkatkan.
adam0101
1

Jika Anda ingin memperkecil ukuran menjadi desimal (7,2) dari desimal (9,2), Anda harus memperhitungkan data yang ada dengan nilai yang lebih besar untuk dimasukkan ke dalam desimal (7,2). Anda harus menghapus angka-angka itu dan memotongnya agar sesuai dengan ukuran baru Anda. Jika tidak ada data untuk bidang yang Anda coba perbarui, itu akan melakukannya secara otomatis tanpa masalah

Benoy John
sumber
0

Gunakan fungsi TRY_CAST dengan cara yang sama persis dengan fungsi CAST. TRY_CAST mengambil string dan mencoba mentransmisikannya ke tipe data yang ditentukan setelah kata kunci AS. Jika konversi gagal, TRY_CAST mengembalikan NULL bukannya gagal.

Bharat
sumber
1
TRY_CAST mengambil ekspresi, yang nilainya diberikan. Bukan hanya string seperti yang Anda katakan.
TT.
Meskipun itu akan memungkinkan rutinitas selesai tanpa kesalahan, itu akan mengakibatkan hilangnya data. Tujuan dari kesalahan tersebut adalah untuk menunjukkan bahwa intervensi diperlukan untuk mencegah data yang hilang. Solusi Anda hanya akan berhasil jika Anda benar-benar tidak peduli apakah hasilnya ada atau tidak.
Dan
-2

periksa nilai Anda yang ingin Anda simpan di kolom integer. Saya pikir ini lebih besar dari kisaran integer. jika Anda ingin menyimpan nilai lebih besar dari kisaran integer. Anda harus menggunakan tipe data bigint

Pangeran bahagia
sumber
OP menunjukkan bahwa kolom yang dimaksud adalah Numerik, bukan Integer (seperti yang ditunjukkan oleh pesan kesalahan "Kesalahan overflow aritmatika mengonversi numerik ke tipe data numerik."), Dan jawaban atas yang diposting mengatasi ini dengan benar. Jawaban Anda dengan benar mengidentifikasi masalah (ruang tidak cukup untuk menyimpan hasil) tetapi meleset dari maksud asli pertanyaan.
Dan