2011-09-19 28 views
9

Estoy usando openrowset para importar un archivo csv a SQL Server. Una de las columnas en el archivo csv contiene números en notación científica (1.08E + 05) y la columna en la tabla que se está insertandoConvertir notación científica para flotar cuando se usa OpenRowSet para importar un archivo .CSV

Por defecto está importando el valor como 1 e ignorando el .08E + 05.

He intentado usar cast() y convert() para convertir el valor directamente cuando se ejecuta la consulta, así como configurar el tipo de datos en la tabla como una cadena de caracteres e importarla como tal. Todos estos métodos tienen el mismo comportamiento cuando se ignora el .08E + 05.

¿Hay alguna manera de tener el valor importado como 108000 en lugar de 1 sin el .08E + 05 sin tener que cambiar el archivo csv en sí?

Configuración del tipo de datos como un varchar y la lectura en el archivo csv parece tener el mismo efecto con el siguiente código:

CREATE TABLE #dataTemp (StartDate datetime, Value varchar(12)) 

SET @insertDataQuery = 'SELECT Date, CSVValue from OpenRowset(''MSDASQL'', ''Driver={Microsoft Text Driver (*.txt; *.csv)}; DefaultDir=' 
SET @insertDataQuery = @insertDataQuery + 'C:\Data\;'',''SELECT * FROM '+ '11091800.csv' + ''')' 

INSERT INTO #dataTemp EXEC(@insertDataQuery) 

SELECT * FROM #dataTemp 

No todos los valores en el archivo CSV ver la notación científica y la valor sin él, por ejemplo 81000 se encuentran sin problema.

Respuesta

13

Para BULK INSERT metodologías que he encontrado a menudo más fácil de mover primero los datos en una tabla de todos los varchars, a continuación, deshacerse de cosas extrañas como delimitadores citados y fijar el formato. Recuerdo que tuve muchísimo tiempo para deshacerme de la notación científica, puedes simplemente jugar con la tabla varchar hasta que lo hagas bien. Recuerdo haber intentado todo tipo de combinaciones de precisión/escala hasta que finalmente encontré uno que era compatible. Creo que para mí fue FLOAT continuación DECIMAL(24,12) ...

SELECT CONVERT(DECIMAL(24, 12), CONVERT(FLOAT, '1.08E+05'));

EDITAR añadiendo lo que hice para tratar de repro y/o demostrar una manera menos complicada.

he creado un archivo CSV muy simple:

StartDate,Value 
20110808,81000 
20110808,1.08E+05 

Entonces me encontré con el siguiente código (por alguna razón no puedo conseguir MSDASQL para ejecutar en mi máquina para salvar mi vida):

CREATE TABLE #dataTemp(StartDate DATETIME, Value VARCHAR(32)); 

BULK INSERT #dataTemp FROM 'C:\data\whatever.csv' 
    WITH (ROWTERMINATOR='\n', FIELDTERMINATOR=',', FIRSTROW = 2); 

SELECT * FROM #dataTemp 
GO 
SELECT StartDate, CONVERT(INT, CONVERT(FLOAT, Value)) FROM #dataTemp; 
GO 
DROP TABLE #dataTemp; 

resultados:

StartDate    Value 
----------------------- -------- 
2011-08-08 00:00:00.000 81000 
2011-08-08 00:00:00.000 1.08E+05 

StartDate    (No column name) 
----------------------- ---------------- 
2011-08-08 00:00:00.000 81000 
2011-08-08 00:00:00.000 108000 
+1

En realidad, en su caso, ahora que estoy re-leer la pregunta probablemente puede utilizar SELECT CONVERT (INT , CONVERTIR (FLOTAR, '1.08E + 05 ')); '- la última vez que trabajé en notación científica estaba tratando con contadores de rendimiento de LogMan, y definitivamente necesitaba los lugares decimales ... –

+0

Cualquiera de las soluciones anteriores funciona si proporciono el valor explícitamente. En el archivo CSV tengo un nombre de columna para el valor y si lo uso, por ejemplo, CONVERT (INT, CONVERT (FLOAT, COLUMN_NAME_IN_CSV)) sigo teniendo el comportamiento en el que solo lee el primer dígito. ¿Pensamientos? – amarcy

+0

Mis pensamientos todavía están en insertarlos a granel en una tabla de varchar primero. Puede haber algo más cuando su inserción ... seleccione desde la consulta openrowset está tratando de hacer coincidir los tipos de tabla con los metadatos de la consulta. Si está insertando en varchar primero, no va a importar ... –

4

¿Lo convertirá en un verdadero trabajo?

select cast('1.08E+05' as real) 
5

en primer lugar, el hecho de que tienen una notación científica significa que es probable Excel o algún otro programa que creó el valor ha PERDIDO algunos datos ... en otras palabras, el número original dentro de la notación se ha convertido y se han perdido algunos números y precisión. Eso es un problema con muchos productos de Microsoft que convierten desde Excel y CSV.

En segundo lugar, aquí hay una piefce la mejor conversión que convierte el número en una cadena:

CONVERT(nvarchar(255),LTRIM(RTRIM(str(ISNULL(YOUR_NUMBER,0),20,0)))) 
+1

..... ha PERDIDO algunos datos ...... eso es un problema con muchos productos de Microsoft que convierten de Excel y CSV ..... exactamente. Mas uno. No tener Excel instalado es prácticamente un requisito previo para cualquier tipo de trabajo de datos. El problema es que conseguir que sus clientes desinstalen Excel es bastante difícil :) – DaveBoltman

Cuestiones relacionadas