Errore di overflow aritmetico durante la conversione di un tipo di dati numerico in un tipo di dati numerico


88

Continuo a ricevere questo messaggio di errore ogni volta che eseguo questa query:

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

Ma se cambio la tabella di creazione in (7,0), non ricevo il messaggio di errore, ma ho bisogno che i miei dati vengano visualizzati come decimali. Ho provato 8,3 non funziona.

C'è qualcuno che può aiutarmi a lavorare su questo? Qualsiasi aiuto sarà molto apprezzato.

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
Non ho nemmeno intenzione di
metterlo in ordine

3
Ho scaricato il tuo SQL tramite il formattatore online qui. dpriver.com/pp/sqlformat.htm Potrebbe ancora fare con un riordino manuale però.
Martin Smith

3
perché l'opzione di un formattatore non è integrata?
adolf garlic

6
Microsoft, se stai ascoltando, viene visualizzato il messaggio di errore "Messaggio 8115, livello 16, stato 8, errore di overflow aritmetico di riga 1 durante la conversione di un numero numerico in un tipo di dati numerico". potrebbe essere migliorato indicando il valore originale che non è stato possibile convertire. Ciò aiuterebbe molto quando si carica una tabella di 100 miliardi di righe e si cerca di capire quale valore sia offensivo. L'aggiunta del numero di colonna di un SELECT sarebbe di nuovo utile. PER ESEMPIO. SELEZIONA CAST (12345678910 come decimale (12,0)), CAST (12345678910 come decimale (12,2)) ... aggiungi la stringa: "Valore: 12345678910 Colonna: 2" al messaggio di errore.
wwmbes

Risposte:


206

La mia ipotesi è che tu stia cercando di inserire un numero maggiore di 99999,99 nei campi decimali. Cambiarlo in (8,3) non farà nulla se è maggiore di 99999.999: devi aumentare il numero di cifre prima del decimale. Puoi farlo aumentando la precisione (che è il numero totale di cifre prima e dopo il decimale). È possibile lasciare la scala uguale a meno che non sia necessario modificare il numero di posizioni decimali da memorizzare. Prova decimal(9,2)o decimal(10,2)o qualsiasi altra cosa.

Puoi verificarlo commentando insert #tempe vedere quali numeri ti dà l'istruzione select e vedi se sono più grandi di quanto la tua colonna può gestire.


17
Non mi preoccuperei di rispondere alle domande di persone con account generati automaticamente; non capiscono dove sono e non tornano una volta che hanno avuto la loro correzione. @ user572984: CIAO !? QUALCUNO A CASA? <tocca lo schermo> No, non la pensavo così.
Ola Tuvesson

Avevo tolto il punto del numero decimale, quindi è diventato più grande. Grazie!
Wellington Lorindo

Seleziona Database field lengthuguale per DataTableAdapterla Lunghezza di quella colonna specifica - Parametro specifico della procedura memorizzata Lunghezza
Elshan

1
@OlaTuvesson, fortunatamente, sebbene User572984 sia lungo e probabilmente non lo vedrà mai, ad oggi (8 ottobre 2020) è stato visto oltre 270K volte! Quindi, restituendolo a UnknownUser, ne ha beneficiato fino a 270.000 utenti SO!
Dan

83

Sento di dover chiarire una cosa molto importante, per gli altri (come il mio collega) che si sono imbattuti in questo thread e hanno ottenuto le informazioni sbagliate.

La risposta fornita ("Prova decimale (9,2) o decimale (10,2) o qualsiasi altra cosa.") È corretta, ma il motivo ("aumenta il numero di cifre prima del decimale") è sbagliato.

decimale (p, s) e numerico (p, s) specificano entrambi una precisione e una scala . La "precisione" non è il numero di cifre a sinistra del decimale, ma è invece la precisione totale del numero.

Ad esempio: decimale (2,1) copre da 0,0 a 9,9, perché la precisione è di 2 cifre (da 00 a 99) e la scala è 1. decimale (4,1) da 000,0 a 999,9 decimale (4,2) da 00,00 a 99,99 decimale (4,3) copre da 0,000 a 9,999


7
Aumentando la precisione e lasciando la scala stessa, si sta aumentando il numero di cifre prima del decimale. Quindi quello che ho detto non è sbagliato, ma vedo come potrebbe essere frainteso. L'ho detto in questo modo perché originariamente l'OP stava cercando di risolvere il problema semplicemente aumentando la scala, ma hai ragione; è la precisione totale che deve essere aumentata.
adam0101

1

Se vuoi ridurre la dimensione al decimale (7,2) dal decimale (9,2) dovrai tenere conto dei dati esistenti con valori maggiori per rientrare nel decimale (7,2). O dovrai eliminare quei numeri e troncarli per adattarli alla tua nuova dimensione. Se non c'erano dati per il campo che stai tentando di aggiornare, lo farà automaticamente senza problemi


0

Usa la funzione TRY_CAST esattamente allo stesso modo della funzione CAST. TRY_CAST accetta una stringa e prova a trasmetterla a un tipo di dati specificato dopo la parola chiave AS. Se la conversione non riesce, TRY_CAST restituisce un NULL invece di fallire.


1
TRY_CAST accetta un'espressione, il cui valore viene lanciato. Non solo stringhe come dici tu.
TT.

Sebbene ciò consentirebbe il completamento della routine senza errori, sarebbe a costo della mancanza di dati. Lo scopo dell'errore è indicare che è necessario un intervento per evitare la perdita di dati. La tua soluzione funzionerebbe solo se davvero non ti interessa se il risultato è presente o meno.
Dan

-2

controlla il valore che desideri memorizzare nella colonna dei numeri interi. Penso che questo sia maggiore dell'intervallo di numeri interi. se si desidera memorizzare un valore maggiore dell'intervallo intero. dovresti usare il tipo di dati bigint


L'OP indica che la colonna in questione è numerica, non intera (come indicato dal messaggio di errore "Errore di overflow aritmetico durante la conversione di un numero numerico in un tipo di dati numerico.") E la risposta pubblicata in alto lo affronta correttamente. La tua risposta identifica correttamente il problema (spazio insufficiente per memorizzare il risultato) ma manca lo scopo originale della domanda.
Dan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.