Problema al cargar, convertir números con muchos decimales

FREDDY PEREZ 0 Puntos de reputación
2024-02-03T03:30:28.3533333+00:00

Hola, Estoy cargando una base de datos desde un TXT que tiene 50 millones de registros, utilizo BULK INSERT para hacerlo, varias columnas tiene números con este formato 9063,664733395696913002806361085126286249 intente con el asistente pero es muy lento y al final no lograba cargar los datos. No logre cargar estas columnas como valor numero (intentando varias opciones , float, decimal(38,38), entre otros) para que lo reconociera como numero así que lo cargue como texto para convertirlo posteriormente. Entiendo que no logra cargarlo por el largo del numero..... Luego de cargarlo utilizo esta función que se ve a continuación

   select 
  sum(try_convert (decimal(38, 20), Coalesce (replace( substring([VlrPagadoPBStxt],0,20), ',','.'),0))) PagoPBS, 
  sum(try_convert (decimal(38, 20), Coalesce (replace( substring([VlrPagadoPMtxt],0,20) , ',','.' ), 0 ))) PagoPM -
  from [etNov23].dbo.[192-4]

imagen_2024-02-02_221719436

como se observa en la última foto, aun haciendo recorte al valor y realizando reemplazos de "," por "." no es posible que realice la operación. en alguna base similar realice el mismo proceso y lo consigui pero el valor sumado perdia 0.02% del valor total. ¿Que debo corregir en mi proceso? ¿Se trata de un bug? Muchas gracias.

SQL Server
SQL Server
Familia de sistemas de análisis y administración de bases de datos relacionales de Microsoft para soluciones de comercio electrónico, línea de negocio y almacenamiento de datos.
40 preguntas
0 comentarios No hay comentarios
{count} votos

1 respuesta

Ordenar por: Muy útil
  1. javi Fernandez 105 Puntos de reputación
    2024-02-04T02:42:44.89+00:00

    Yo no veo ningún bug, si en alguna base lo conseguiste y en otra no, será porque los datos son diferentes, y si lo son y te da un error, será porque te excedes de algún rango permitido. Los números de precisión exacta no pueden disponer de más de 38 dígitos. Se me ocurre lo siguiente. Según el ejemplo que expones.

    
    Declare @var varchar(100) = '9063,664733395696913002806361085126286249';
    
    Select 
    -- extraemos la parte a la izquierda de la coma.
    LEFT(@var,
    	 case
    		 when charindex(',', @var) > 0 then
    											charindex(',', @var) - 1
    	 else 0
    	 end)
    -- extraemos la parte de la derecha de la coma
    , RIGHT(@var,
    		case
    			when charindex(',', @var) > 0 then
    											   LEN(@VAR) - charindex(',', @var)
    		else LEN(@VAR)
    		end)
    -- Esta sería la parte entera en un decimal
    , TRY_CAST(LEFT(@var,
    			case
    				when charindex(',', @var) > 0 then
    												   charindex(',', @var) - 1
    			else 0
    			end) AS decimal(38, 0))
    -- Esta sería la parte flotante en un decimal
    , CAST(RIGHT(@var,
    			 case
    				 when charindex(',', @var) > 0 then
    													LEN(@VAR) - charindex(',', @var)
    			 else LEN(@VAR)
    			 END) AS decimal(38, 0));
    

    El resultado. User's image

    De esta forma, tienes el número completo. Luego ya el tratamiento que le des, es otro escenario. Decimal y Numeric Float y Real