Importación masiva de SQL desde CSV

Necesito importar un gran archivo CSV en un servidor SQL. Estoy usando esto:

BULK 
INSERT CSVTest
        FROM 'c:\csvfile.txt'
            WITH
    (
                FIELDTERMINATOR = ',',
                ROWTERMINATOR = '\n'
    )
GO

El problema es que todos mis campos están rodeados por comillas ("") así que una fila realmente se ve así:

"1","","2","","sometimes with comma , inside", "" 

¿Puedo, de alguna manera, importarlos a granel y decirle a SQL que use las comillas como delimitadores de campo?

Edit: The problem with using '","' as delimiter, as in the examples suggested is that : What most examples do, is they import the data including the first " in the first column and the last " in the last, then they go ahead and strip that out. Alas my first (and last) column are datetime and will not allow a "20080902 to be imported as datetime.

Por lo que he estado leyendo, creo que FORMATFILE es el camino a seguir, pero la documentación (incluida MSDN) es tremendamente inútil.

0
agregado editado
Puntos de vista: 1
Debería volver a etiquetar este sqlserver para que sepamos qué base de datos está utilizando.
agregado el autor JasonS, fuente

12 Respuestas

Debe tener cuidado con BCP/BULK INSERT porque ni BSP ni Bulk Insert lo manejan bien si las citas no son consistentes, incluso con archivos de formato (incluso los archivos de formato xml no ofrecen la opción) y caracteres ficticios ["] en el principio y final y utilizando [","] como separador. Técnicamente, los archivos CSV no necesitan tener caracteres ["] si no hay caracteres incrustados []

Es por esta razón que los archivos delimitados por comas a veces se denominan archivos de comedia limitada.

OpenRowSet requerirá Excel en el servidor y podría ser problemático en entornos de 64 bits: sé que es problemático al usar Excel en Jet en 64 bits.

SSIS es realmente su mejor opción si el archivo es probable que varíe de sus expectativas en el futuro.

0
agregado

Yup, K Richard is right: FIELDTERMINATOR = '","'

Consulte http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file para más información.

0
agregado

Pruebe OpenRowSet . Esto se puede usar para importar cosas de Excel. Excel puede abrir archivos CSV, por lo que solo necesita averiguar el [ConnectionString] correcto [2].

[2]: Driver = {Microsoft Text Driver (* .txt; * .csv)}; Dbq = c: \ txtFilesFolder \; Extensiones = asc, csv, tab, txt;

0
agregado

Otro truco que a veces uso es abrir el archivo CSV en Excel y luego escribir el enunciado SQL en una celda al final de cada fila. Por ejemplo:

=concatenate("insert into myTable (columnA,columnB) values ('",a1,"','",b1,"'")")

Un relleno puede llenarlo en cada fila. Luego solo copie y pegue el resultado en una nueva ventana de consulta.

Es de la vieja escuela, pero si solo tienes que hacer importaciones de vez en cuando, te ahorra perder el tiempo leyendo toda la oscura documentación sobre la forma "correcta" de hacerlo.

0
agregado
Buen consejo, @jorgeburgos
agregado el autor karlgrz, fuente
Sé que esta respuesta es antigua, pero acabo de llegar con una búsqueda en Google para algo similar. Este es un buen momento para generar cualquier código a partir de datos tabulares, no solo código para cargar una declaración SQL. Puede colocar una plantilla en algún lugar del archivo de Excel, luego haga = SUBSTITUTE ($ Z $ 999, "placeholder_a", "'" & SUBSTITUTE (A2, "'", "''") & "'"), "placeholder_b", SUSTITUTO (B2, "'", "' '")) . Suponiendo que tiene una plantilla en $ Z $ 999.
agregado el autor Don 01001100, fuente
Buen consejo, gracias!
agregado el autor DanB, fuente

¿Necesitas hacer esto programáticamente, o es un disparo de una sola vez?

Con el Administrador corporativo, haga clic con el botón secundario en Importar datos para seleccionar su delimitador.

0
agregado

Si descubres cómo descomprimir el archivo en una DataTable, te sugiero la clase SqlBulkInsert para insertarlo en SQL Server.

0
agregado

También podría usar DTS o SSIS.

0
agregado

Try FIELDTERMINATOR='","'

Aquí hay un gran enlace para ayudar con la primera y última cita ... mire cómo usó la subcadena SP

http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file

0
agregado
A mi también me sirvió. Estoy usando un archivo de formato xml para que se use el atributo Terminator en lugar de FIELDTERMINATOR. Además, en mi última columna utilicé el siguiente TERMINATOR = '"\ r \ n'
agregado el autor Craig McKeachie, fuente
No funcionará :-(. El primer campo de la tabla es una fecha e importará la comilla principal (") con ella, generando un error.
agregado el autor Radu094, fuente
También tenga cuidado con las aplicaciones que exportan CSV con cadenas citadas pero números no citados.
agregado el autor finnw, fuente

¿Tienes control sobre el formato de entrada? | (tuberías), y \ t generalmente hacen mejores terminadores de campo.

0
agregado

Sé que esta no es una solución real, pero utilizo una tabla ficticia para la importación con nvarchar configurado para todo. Luego hago una inserción que elimina los "caracteres y hace las conversiones. No es bonita, pero cumple su función.

0
agregado
¿Cómo se dividen los campos cuando puede haber comas entre las comillas?
agregado el autor Jeremy Stein, fuente

Id decir usar FileHelpers es una biblioteca de código abierto

0
agregado

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);
                }
            }
        }
    }
}
0
agregado