Arithmetischer Überlauffehler beim Konvertieren von numerischen in numerische Datentypen

86

Ich erhalte jedes Mal diese Fehlermeldung, wenn ich diese Abfrage ausführe:

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

Wenn ich jedoch die Erstellungs-Tabelle in (7,0) ändere, wird die Fehlermeldung nicht angezeigt. Meine Daten müssen jedoch als Dezimalzahl angezeigt werden. Ich habe versucht 8,3 funktioniert nicht.

Gibt es jemanden, der mir dabei helfen kann? Jede Hilfe wird sehr geschätzt.

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  
user572984
quelle
9
Ich werde nicht einmal anfangen, das
aufzuräumen
3
Ich habe Ihre SQL hier durch den Online-Formatierer geworfen. dpriver.com/pp/sqlformat.htm Könnte aber trotzdem ein manuelles Aufräumen vertragen .
Martin Smith
3
Warum ist die Option eines Formatierers nicht integriert?
Adolf Knoblauch
4
Microsoft, wenn Sie zuhören, wird die Fehlermeldung "Nachricht 8115, Ebene 16, Status 8, Zeile 1 Arithmetischer Überlauffehler beim Konvertieren von numerischen in numerische Datentypen" angezeigt. könnte verbessert werden, indem der ursprüngliche Wert angegeben wird, der nicht konvertiert werden konnte. Das würde sehr helfen, wenn Sie eine Tabelle mit 100 Mrd. Zeilen laden und versuchen zu verstehen, welcher Wert beleidigend ist. Das Hinzufügen der Spaltennummer eines SELECT wäre ebenso nützlich. Z.B. SELECT CAST (12345678910 als Dezimalzahl (12,0)), CAST (12345678910 als Dezimalzahl (12,2)) ... fügen Sie der Fehlermeldung die Zeichenfolge "Wert: 12345678910 Spalte: 2" hinzu.
wwmbes

Antworten:

202

Ich vermute, dass Sie versuchen, eine Zahl größer als 99999,99 in Ihre Dezimalfelder zu drücken. Das Ändern auf (8,3) führt zu nichts, wenn es größer als 99999.999 ist. Sie müssen die Anzahl der Stellen vor der Dezimalstelle erhöhen . Sie können dies tun, indem Sie die Genauigkeit erhöhen (dies ist die Gesamtzahl der Stellen vor und nach der Dezimalstelle). Sie können die Skala beibehalten, es sei denn, Sie müssen die Anzahl der zu speichernden Dezimalstellen ändern. Versuchen Sie decimal(9,2)oder decimal(10,2)oder was auch immer.

Sie können dies testen, indem Sie die auskommentieren insert #tempund sehen, welche Zahlen die select-Anweisung Ihnen gibt, und sehen, ob sie größer sind, als Ihre Spalte verarbeiten kann.

adam0101
quelle
17
Ich würde mir nicht die Mühe machen, Fragen von Leuten mit automatisch generierten Konten zu beantworten. Sie verstehen nicht, wo sie sind und kommen nicht zurück, wenn sie ihre Probleme gelöst haben. @ user572984: HALLO!? IST JEMAND ZUHAUSE? <tippt auf den Bildschirm> Nein, das habe ich nicht gedacht.
Ola Tuvesson
Ich hatte den Dezimalpunkt entfernt, damit er größer wurde. Vielen Dank!
Wellington Lorindo
Überprüfen Sie Database field lengthgleich, um DataTableAdapterder Länge dieser bestimmten Spalte - dem spezifischen Parameter der gespeicherten Prozedur Länge
Elshan
80

Ich denke, ich muss eine sehr wichtige Sache für andere (wie meinen Kollegen) klären, die auf diesen Thread gestoßen sind und die falschen Informationen erhalten haben.

Die Antwort ("Versuchen Sie es mit Dezimalzahl (9,2) oder Dezimalzahl (10,2) oder was auch immer.") Ist korrekt, aber der Grund ("Erhöhen Sie die Anzahl der Stellen vor der Dezimalstelle") ist falsch.

Dezimal (p, s) und numerisch (p, s) geben sowohl eine Präzision als auch eine Skala an . Die "Genauigkeit" ist nicht die Anzahl der Stellen links von der Dezimalstelle, sondern die Gesamtgenauigkeit der Zahl.

Beispiel: Dezimal (2,1) deckt 0,0 bis 9,9 ab, da die Genauigkeit 2 Stellen (00 bis 99) und die Skala 1 beträgt. Dezimal (4,1) deckt 000,0 bis 999,9 ab. Dezimal (4,2) deckt 00,00 bis 9,9 ab 99,99 Dezimal (4,3) deckt 0,000 bis 9,999 ab

Dan
quelle
7
Durch die Präzision zu erhöhen und die Skala das gleiche verlassen, Sie sind eine Erhöhung der Anzahl der Stellen vor dem Komma. Was ich gesagt habe, ist also nicht falsch, aber ich sehe, wie es missverstanden werden könnte. Ich habe es so gesagt, weil das OP ursprünglich versucht hat, das Problem zu beheben, indem es nur den Maßstab vergrößert hat, aber Sie haben Recht. Es ist die Gesamtpräzision, die erhöht werden muss.
Adam0101
1

Wenn Sie die Größe von dezimal (9,2) auf dezimal (7,2) reduzieren möchten, müssen Sie die vorhandenen Daten mit Werten berücksichtigen, die größer sind, um in dezimal (7,2) zu passen. Entweder müssen Sie diese Zahlen löschen, indem Sie sie abschneiden, um sie an Ihre neue Größe anzupassen. Wenn für das Feld, das Sie aktualisieren möchten, keine Daten vorhanden waren, wird dies automatisch ohne Probleme ausgeführt

Benoy John
quelle