Importar archivo CSV en SQL Server

186

Estoy buscando ayuda para importar un .csvarchivo a SQL Server usando BULK INSERTy tengo algunas preguntas básicas.

Cuestiones:

  1. Los datos del archivo CSV pueden tener ,(coma) entre (Ejemplo: descripción), entonces, ¿cómo puedo hacer que la importación maneje estos datos?

  2. Si el cliente crea el CSV desde Excel, entonces los datos que tienen una coma están encerrados entre ""comillas dobles (como en el ejemplo a continuación), entonces, ¿cómo puede manejar esto la importación?

  3. ¿Cómo rastreamos si algunas filas tienen datos incorrectos, que importan saltos? (importa saltos de filas que no son importables)

Aquí está el CSV de muestra con encabezado:

Name,Class,Subject,ExamDate,Mark,Description
Prabhat,4,Math,2/10/2013,25,Test data for prabhat.
Murari,5,Science,2/11/2013,24,"Test data for his's test, where we can test 2nd ROW, Test."
sanjay,4,Science,,25,Test Only.

Y declaración SQL para importar:

BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    TABLOCK
)
Prabhat
fuente
Puede ser SSMS: cómo importar (copiar / pegar) datos de Excel puede ayudar (si no desea usar BULK NSERTo no tiene permisos para ello).
Denis

Respuestas:

169

Importación CSV de SQL Server basada

1) Los datos del archivo CSV pueden tener ,(coma) entre (Ejemplo: descripción), entonces, ¿cómo puedo hacer que la importación maneje estos datos?

Solución

Si está utilizando ,(coma) como delimitador, entonces no hay forma de diferenciar entre una coma como un terminador de campo y una coma en sus datos. Yo usaría un me FIELDTERMINATORgusta diferente ||. El código se vería así y esto manejará perfectamente una coma y una barra diagonal.

2) Si el cliente crea el csv a partir de Excel, entonces los datos que tienen una coma están encerrados dentro " ... "(comillas dobles) [como el ejemplo a continuación] entonces, ¿cómo puede manejar la importación esto?

Solución

Si está utilizando la inserción BULK, entonces no hay forma de manejar comillas dobles, los datos se insertarán con comillas dobles en filas. después de insertar los datos en la tabla, puede reemplazar esas comillas dobles con ' '.

update table
set columnhavingdoublequotes = replace(columnhavingdoublequotes,'"','')

3) ¿Cómo rastreamos si algunas filas tienen datos incorrectos, que importan saltos? (¿Importa omite filas que no son importables)?

Solución

Para manejar filas que no se cargan en la tabla debido a datos o formato no válidos, podría manejarse usando la propiedad ERRORFILE , especifique el nombre del archivo de error, escribirá las filas que tienen un error en el archivo de error. el código debería verse así.

BULK INSERT SchoolsTemp
    FROM 'C:\CSVData\Schools.csv'
    WITH
    (
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    ERRORFILE = 'C:\CSVDATA\SchoolsErrorRows.csv',
    TABLOCK
    )
Vishwanath Dalvi
fuente
1
Gracias por la ayuda. Reg la Solución # 1: ¿Podemos crear || archivo de valores separados de Excel? Porque el cliente crea alrededor del 20% de los archivos de origen utilizando Excel.
Prabhat
@Prabhat ¿Cómo está cargando archivos de Excel en SQL Server?
Vishwanath Dalvi
Estos no son archivos de Excel que estoy cargando. El cliente está utilizando Excel para crear archivos .CSV (para el 20% de los datos de origen que importa nuestra aplicación). Y estaba preguntando si creamos archivos csv usando Excel, ¿cómo podemos tener || como separador de valor de columna?
Prabhat
Si tiene influencia sobre cómo el cliente crea archivos CSV desde Excel, puede enseñarles cómo configurar el carácter separador en Excel (y bueno, ya no es un archivo separado por "comas", sería separado por una tubería (|), por ejemplo. Dados los obstáculos por los que estás saltando para esto, y si tienes SSIS, te recomiendo que lo verifiques. Las versiones de SQL Server 2012 y posteriores tienen un diseñador SSIS muy robusto (también en VS 2012 y posteriores) que
Permita
No estoy seguro de que esto sea completamente exacto. Puede tratar con comillas dobles en la inserción masiva de SQL. Hay un desbordamiento de pila sobre este tema y uno puede usar archivos de formato para enseñar delimitadores variables de inserción masiva. stackoverflow.com/questions/25726385/... advancesharp.com/blog/1083/...
DtechNet
33

Primero debe crear una tabla en su base de datos en la que va a importar el archivo CSV. Después de crear la tabla, siga los pasos a continuación.

• Inicie sesión en su base de datos usando SQL Server Management Studio

• Haga clic derecho en su base de datos y seleccione Tasks -> Import Data...

• Haz clic en el Next >botón

• Para la Fuente de datos, seleccione Flat File Source. Luego use el botón Examinar para seleccionar el archivo CSV. Dedique un tiempo a configurar cómo desea que se importen los datos antes de hacer clic en el Next >botón.

• Para el Destino, seleccione el proveedor de base de datos correcto (por ejemplo, para SQL Server 2012, puede usar SQL Server Native Client 11.0). Ingrese el nombre del servidor. Verifique el Use SQL Server Authenticationbotón de radio. Ingrese el Nombre de usuario, Contraseña y Base de datos antes de hacer clic en el Next >botón.

• En la ventana Seleccionar tablas y vistas de origen, puede editar asignaciones antes de hacer clic en el Next >botón.

• Marque la Run immediatelycasilla de verificación y haga clic en el Next >botón.

• Haga clic en el Finishbotón para ejecutar el paquete.

Lo anterior se encontró en este sitio web (lo he usado y probado):

Zd8n8k
fuente
30
Sería bueno si le atribuye la página donde copió / pegó esta respuesta de ...
SierraOscar
1
No es necesario crear previamente la tabla, se puede crear durante el proceso de importación
bside
1
Me encanta que simplemente corte y pegue desde una página web con la línea tan útil "Dedique un tiempo a configurar cómo desea que se importen los datos" . Eso fue todo lo que estaba buscando: ¡parece que no puedo configurarlo en absoluto!
Auspex
Ah, y "Verificar el botón de opción Usar autenticación del servidor SQL" está mal, ya que es muy posible que desee usar la autenticación de Windows. Es lo que funcione para ti.
Auspex
gracias encontró un procedimiento paso a paso con imágenes para implementar el procedimiento anterior, vale la pena echarle un vistazo: qawithexperts.com/article/sql/…
user3559462
23

2) Si el cliente crea el csv a partir de Excel, los datos que tienen una coma están encerrados dentro de "..." (comillas dobles) [como el ejemplo a continuación] entonces, ¿cómo puede manejar la importación esto?

Debe usar las opciones FORMAT = 'CSV', FIELDQUOTE = '"':

BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
    FORMAT = 'CSV', 
    FIELDQUOTE = '"',
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',  --CSV field delimiter
    ROWTERMINATOR = '\n',   --Use to shift the control to next row
    TABLOCK
)
Oleg
fuente
1
Tenga en cuenta que el especificador FORMAT solo está disponible desde SQL Server 2017.
kristianp
13

La mejor, la forma más rápida y fácil de resolver el problema de la coma en los datos es usar Excel para guardar un archivo separado por comas después de haber configurado la configuración del separador de listas de Windows en algo distinto de una coma (como una tubería). Esto generará un archivo separado de tubería (o lo que sea) que luego podrá importar. Esto se describe aquí .

Sachin Kainth
fuente
4

Primero debes importar el archivo CSV a la tabla de datos

Luego puede insertar filas masivas usando SQLBulkCopy

using System;
using System.Data;
using System.Data.SqlClient;

namespace SqlBulkInsertExample
{
    class Program
    {
      static void Main(string[] args)
        {
            DataTable prodSalesData = new DataTable("ProductSalesData");

            // Create Column 1: SaleDate
            DataColumn dateColumn = new DataColumn();
            dateColumn.DataType = Type.GetType("System.DateTime");
            dateColumn.ColumnName = "SaleDate";

            // Create Column 2: ProductName
            DataColumn productNameColumn = new DataColumn();
            productNameColumn.ColumnName = "ProductName";

            // Create Column 3: TotalSales
            DataColumn totalSalesColumn = new DataColumn();
            totalSalesColumn.DataType = Type.GetType("System.Int32");
            totalSalesColumn.ColumnName = "TotalSales";

            // Add the columns to the ProductSalesData DataTable
            prodSalesData.Columns.Add(dateColumn);
            prodSalesData.Columns.Add(productNameColumn);
            prodSalesData.Columns.Add(totalSalesColumn);

            // Let's populate the datatable with our stats.
            // You can add as many rows as you want here!

            // Create a new row
            DataRow dailyProductSalesRow = prodSalesData.NewRow();
            dailyProductSalesRow["SaleDate"] = DateTime.Now.Date;
            dailyProductSalesRow["ProductName"] = "Nike";
            dailyProductSalesRow["TotalSales"] = 10;

            // Add the row to the ProductSalesData DataTable
            prodSalesData.Rows.Add(dailyProductSalesRow);

            // Copy the DataTable to SQL Server using SqlBulkCopy
            using (SqlConnection dbConnection = new SqlConnection("Data Source=ProductHost;Initial Catalog=dbProduct;Integrated Security=SSPI;Connection Timeout=60;Min Pool Size=2;Max Pool Size=20;"))
            {
                dbConnection.Open();
                using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
                {
                    s.DestinationTableName = prodSalesData.TableName;

                    foreach (var column in prodSalesData.Columns)
                        s.ColumnMappings.Add(column.ToString(), column.ToString());

                    s.WriteToServer(prodSalesData);
                }
            }
        }
    }
}
kombsh
fuente
un contenedor quizás más fácil de usar alrededor de las clases de BulkCopy busybulkcopy.codeplex.com
busytools
3

Así es como lo resolvería:

  1. Simplemente guarde su archivo CSV como una hoja XLS en Excel (al hacerlo, no tendrá que preocuparse por los delimitadores. El formato de hoja de cálculo de Excel se leerá como una tabla y se importará directamente a una tabla SQL)

  2. Importar el archivo usando SSIS

  3. Escriba una secuencia de comandos personalizada en el administrador de importación para omitir / modificar los datos que está buscando (o ejecute una secuencia de comandos maestra para examinar los datos que desea eliminar)

Buena suerte.

Zee
fuente
3
Voto negativo: Importar archivos XLS con SSIS es terrible. SSIS intentará adivinar los tipos de datos de los datos de Excel, pero puede adivinar mal y no hay nada que pueda hacer al respecto. Mucho mejor usar CSV.
NReilingh
Bueno, también sugeriría csv, pero si hubiera leído el escenario del OP, tenía algunos escenarios especiales, especialmente con delimitadores, que no son un problema con las hojas xls. Por lo general, los casos especiales como estos no requieren una solución extensa, sino una solución que conserve los datos. Mientras carga el archivo, SSIS le permite elegir el mapeo de datos entre las tablas de origen y destino, lo que nuevamente facilita el esfuerzo involucrado. Es por eso que este método se sugirió como un truco rápido.
Zee
1
SSIS ya puede manejar delimitadores de texto CSV. Si de todos modos está utilizando SSIS, tomarse la molestia de guardar su CSV como un XLS primero me parece que agrega una posible rotura sin ninguna razón.
NReilingh
Además, rutinariamente tengo archivos CSV demasiado grandes para Excel.
Auspex
3

Como no usan el asistente de importación de SQL, los pasos serían los siguientes:

ingrese la descripción de la imagen aquí

  1. Haga clic derecho en la base de datos en la opción de tareas para importar datos,

  2. Una vez que el asistente está abierto, seleccionamos el tipo de datos a implicar. En este caso sería el

Fuente de archivo plano

Seleccionamos el archivo CSV, puede configurar el tipo de datos de las tablas en el CSV, pero es mejor traerlo del CSV.

  1. Haga clic en Siguiente y seleccione la última opción que sea

Cliente SQL

Dependiendo de nuestro tipo de autenticación lo seleccionamos, una vez hecho esto, aparece una opción muy importante.

  1. Podemos definir la identificación de la tabla en el CSV (se recomienda que las columnas del CSV se llamen igual que los campos de la tabla). En la opción Editar asignaciones podemos ver la vista previa de cada tabla con la columna de la hoja de cálculo, si queremos que el asistente inserte la identificación por defecto, dejamos la opción sin marcar.

Habilitar inserción de ID

(generalmente no comienza desde 1), en cambio, si tenemos una columna con la identificación en el CSV, seleccionamos la inserción de identificación de habilitación, el siguiente paso es finalizar el asistente, podemos revisar los cambios aquí.

Por otro lado, en la siguiente ventana pueden aparecer alertas, o advertencias lo ideal es ignorar esto, solo si dejan error es necesario prestar atención.

Este enlace tiene imágenes .

jarvis24
fuente
0

Importe el archivo en Excel abriendo primero Excel, luego vaya a DATOS, importe desde el archivo TXT, elija la extensión csv que conservará 0 valores prefijados y guarde esa columna como TEXTO porque Excel sobresaldrá el 0 inicial de lo contrario (NO haga doble clic para abrir con Excel si tiene datos numéricos en un campo que comienza con un 0 [cero]). Luego solo guarde como un archivo de texto delimitado por tabulaciones. Cuando está importando a Excel, tiene la opción de guardar como GENERAL, TEXTO, etc. Elija TEXTO para que las comillas en el medio de una cadena en un campo como YourCompany, LLC también se conserven ...

BULK INSERT dbo.YourTableName
FROM 'C:\Users\Steve\Downloads\yourfiletoIMPORT.txt'
WITH (
FirstRow = 2, (if skipping a header row)
FIELDTERMINATOR = '\t',
ROWTERMINATOR   = '\n'
)

Desearía poder usar la funcionalidad FORMATO y Fieldquote, pero eso no parece ser compatible con mi versión de SSMS

Steve Yo
fuente
0

Sé que hay respuestas aceptadas, pero aun así, quiero compartir mi escenario que tal vez ayude a alguien a resolver su problema. HERRAMIENTAS

  • ASP.NET
  • CÓDIGO EF-PRIMER ENFOQUE
  • SSMS
  • SOBRESALIR

ESCENARIO Estaba cargando el conjunto de datos que está en formato CSV que luego se mostraría en la Vista. Traté de usar la carga masiva pero no puedo cargar como BULK LOADestaba usando

FIELDTERMINATOR = ','

y la celda Excel también estaba usando , , sin embargo, tampoco pude usar Flat file sourcedirectamente porque estaba usando Code-First Approachy haciendo eso solo hizo el modelo en SSMS DB, no en el modelo desde el que tuve que usar las propiedades más tarde.

SOLUCIÓN

  1. Utilicé la fuente de archivo plano e hice una tabla de base de datos a partir de un archivo CSV ( haga clic con el botón derecho en DB en SSMS -> Importar archivo plano -> seleccione la ruta CSV y realice todas las configuraciones como se indica )
  2. Clase de modelo realizada en Visual Studio (DEBE MANTENER todos los tipos de datos y nombres iguales a los del archivo CSV cargado en sql)
  3. utilizar Add-Migrationen la consola del paquete NuGet
  4. Actualizar DB
Camaleón
fuente
0

Sé que esta no es la solución exacta a la pregunta anterior, pero para mí, fue una pesadilla cuando intentaba copiar datos de una base de datos ubicada en un servidor separado a mi local.

Intenté hacerlo exportando primero los datos del servidor CSV/txty luego importándolos a mi tabla local.

Ambas soluciones: al escribir la consulta para importar CSVo usar el asistente de importación de datos SSMS siempre se producían errores (los errores eran muy generales, indicando que hay un problema de análisis). Y a pesar de que no estaba haciendo especial nada, sólo exportar a CSVy luego tratar de importación CSV a nivel local DB, los errores siempre estaban allí.

Estaba tratando de mirar la sección de mapeo y la vista previa de datos, pero siempre había un gran lío. Y sé que el problema principal provenía de una de las tablecolumnas, que contenía JSONy el SQLanalizador lo estaba tratando mal.

Finalmente, se me ocurrió una solución diferente y quiero compartirla en caso de que alguien más tenga un problema similar.


Lo que hice fue usar el Asistente de exportación en el servidor externo.

Estos son los pasos para repetir el mismo proceso:
1) Haga clic derecho en la base de datos y seleccioneTasks -> Export Data...

2) Cuando se abra el Asistente, elija Siguiente y en lugar de "Fuente de datos:" elija "SQL Server Native Client".

ingrese la descripción de la imagen aquí

En el caso de un servidor externo, lo más probable es que tenga que elegir "Usar autenticación de SQL Server" para el "Modo de autenticación:".

3) Después de presionar Siguiente , debe seleccionar la Descripción .
Para eso, seleccione nuevamente "SQL Server Native Client".
Esta vez puede proporcionar su local (o algún otro externo DB) DB.

ingrese la descripción de la imagen aquí

4) Después de presionar el botón Siguiente, tiene dos opciones: copiar toda la tabla de una DBa otra o escribir la consulta para especificar los datos exactos que se copiarán. En mi caso, no necesitaba toda la tabla (era demasiado grande), sino solo una parte, así que elegí "Escribir una consulta para especificar los datos a transferir".

ingrese la descripción de la imagen aquí

Sugeriría escribir y probar la consulta en un editor de consultas separado antes de pasar al Asistente.

5) Y, por último, debe especificar la tabla de destino donde se seleccionarán los datos.

ingrese la descripción de la imagen aquí

Sugiero dejarlo como [dbo].[Query]o algún Tablenombre personalizado en caso de que tenga errores al exportar los datos o si no está seguro de los datos y desea analizarlos más a fondo antes de pasar a la tabla exacta que desea.

Y ahora ve directamente al final del Asistente presionando los botones Siguiente / Finalizar .

Arsen Khachaturyan
fuente