Error de desbordamiento aritmético al convertir numérico a tipo de datos numérico

88

Sigo recibiendo este mensaje de error cada vez que ejecuto esta consulta:

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

Pero si cambio la tabla de creación a (7,0), no obtengo el mensaje de error. Pero necesito que mis datos se muestren como un decimal. He probado 8,3 no funciona.

¿Hay alguien que pueda ayudarme a trabajar en esto? Cualquier ayuda será muy apreciada.

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  
usuario572984
fuente
9
Ni siquiera voy a empezar a arreglar eso
m.edmondson
3
Lancé su SQL a través del formateador en línea aquí. dpriver.com/pp/sqlformat.htm Sin embargo, aún podría hacerlo con una limpieza manual.
Martin Smith
3
¿Por qué no está incorporada la opción de un formateador?
adolf ajo
6
Microsoft, si está escuchando, aparece el mensaje de error "Msg 8115, Nivel 16, Estado 8, Línea 1 Error de desbordamiento aritmético al convertir numérico a tipo de datos numérico". podría mejorarse indicando el valor original que no se pudo convertir. Eso ayudaría mucho al cargar una tabla de 100 mil millones de filas y tratar de comprender qué valor es ofensivo. Agregar el número de columna de un SELECT sería igualmente útil nuevamente. P.EJ. SELECT CAST (12345678910 como decimal (12,0)), CAST (12345678910 como decimal (12,2)) ... agregue la cadena: "Valor: 12345678910 Columna: 2" al mensaje de error.
wwmbes

Respuestas:

206

Supongo que está intentando introducir un número superior a 99999,99 en sus campos decimales. Cambiarlo a (8,3) no servirá de nada si es mayor que 99999.999; debe aumentar el número de dígitos antes del decimal. Puede hacer esto aumentando la precisión (que es el número total de dígitos antes y después del decimal). Puede dejar la escala igual a menos que necesite modificar la cantidad de decimales que debe almacenar. Tratar decimal(9,2)o decimal(10,2)lo que sea.

Puede probar esto comentando insert #tempy ver qué números le da la declaración de selección y ver si son más grandes de lo que puede manejar su columna.

adam0101
fuente
17
No me molestaría en responder preguntas de personas con cuentas generadas automáticamente; no entienden dónde están y no regresan una vez que han tenido su dosis. @ user572984: ¡HOLA !? ¿ALGUIEN EN CASA? <pantalla táctil> No, no lo creo.
Ola Tuvesson
Quité el punto del número decimal, por lo que se hizo más grande. ¡Gracias!
Wellington Lorindo
Marque Database field lengthes igual a DataTableAdapterla longitud de esa columna específica - Longitud del parámetro específico del procedimiento almacenado
Elshan
1
@OlaTuvesson, afortunadamente, aunque User572984 es largo y probablemente nunca verá esto, a partir de hoy (8 de octubre de 2020) ¡se ha visto más de 270K veces! Por lo tanto, al devolverle el dinero a UnknownUser, ¡ha beneficiado a hasta 270.000 usuarios de SO!
Dan
83

Siento que necesito aclarar una cosa muy importante, para otros (como mi compañero de trabajo) que encontraron este hilo y obtuvieron la información incorrecta.

La respuesta dada ("Pruebe con decimal (9,2) o decimal (10,2) o lo que sea") es correcta, pero la razón ("aumentar el número de dígitos antes del decimal") es incorrecta.

decimal (p, s) y numérico (p, s) ambos especifican una Precisión y una Escala . La "precisión" no es el número de dígitos a la izquierda del decimal, sino la precisión total del número.

Por ejemplo: decimal (2,1) cubre 0.0 a 9.9, porque la precisión es de 2 dígitos (00 a 99) y la escala es 1. decimal (4,1) cubre 000.0 a 999.9 decimal (4,2) cubre 00.00 a 99,99 decimal (4,3) cubre 0,000 a 9,999

Dan
fuente
7
Al aumentar la precisión y dejando la escala de la misma, que está aumentando el número de dígitos antes del decimal. Entonces, lo que dije no está mal, pero veo cómo podría malinterpretarse. Lo dije de esa manera porque originalmente el OP estaba tratando de solucionar el problema simplemente aumentando la escala, pero tienes razón; es la precisión total lo que debe aumentarse.
adam0101
1

Si desea reducir el tamaño a decimal (7,2) desde decimal (9,2), tendrá que contabilizar los datos existentes con valores mayores para que quepan en decimal (7,2). O tendrá que eliminar esos números y truncarlos para que se ajusten a su nuevo tamaño. Si no había datos para el campo que está intentando actualizar, lo hará automáticamente sin problemas.

Benoy John
fuente
0

Utilice la función TRY_CAST exactamente de la misma manera que la función CAST. TRY_CAST toma una cadena e intenta convertirla en un tipo de datos especificado después de la palabra clave AS. Si la conversión falla, TRY_CAST devuelve un NULL en lugar de fallar.

Bharat
fuente
1
TRY_CAST toma una expresión, cuyo valor se lanza. No solo cadenas como las pones.
TT.
Aunque eso permitiría que la rutina se completara sin errores, sería a costa de la falta de datos. El propósito del error es indicar que se requiere intervención para evitar la pérdida de datos. Su solución funcionaría solo si realmente no le importa si el resultado está presente o no.
Dan
-2

verifique el valor que desea almacenar en la columna de números enteros. Creo que esto es mayor que el rango de números enteros. si desea almacenar un valor mayor que el rango de números enteros. deberías usar el tipo de datos bigint

Príncipe feliz
fuente
El OP indica que la columna en cuestión es Numérica, no Entera (como lo indica el mensaje de error "Error de desbordamiento aritmético al convertir numérico en tipo de datos numérico"), y la respuesta publicada en la parte superior aborda esto correctamente. Su respuesta identifica correctamente el problema (espacio insuficiente para almacenar el resultado) pero pierde la intención original de la pregunta.
Dan