23

我需要将一个大型 CSV 文件导入 SQL 服务器。我正在使用这个:

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

问题是我的所有字段都被引号(“”)包围,所以一行实际上看起来像:

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

我可以以某种方式批量导入它们并告诉 SQL 使用引号作为字段分隔符吗?

编辑:使用 '","' 作为分隔符的问题,如示例中所建议的那样:大多数示例所做的是,它们导入的数据包括第一列中的第一个“和最后一列中的最后一个”,然后它们去吧,把它去掉。唉,我的第一列(也是最后一列)是日期时间,不允许将“20080902”作为日期时间导入。

从我一直在阅读的内容来看,我认为 FORMATFILE 是要走的路,但是文档(包括 MSDN)非常无用。

4

14 回答 14

13

尝试FIELDTERMINATOR='","'

这是一个很好的链接,可以帮助第一个和最后一个引号...看看他如何使用子字符串 SP

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

于 2008-09-18T20:20:21.273 回答
10

我有时使用的另一个技巧是在 Excel 中打开 CSV,然后将 sql 语句写入每行末尾的单元格中。例如:

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

填写可以为您将其填充到每一行中。然后只需将输出复制并粘贴到新的查询窗口中。

这是老式的,但是如果您只需要偶尔进行一次导入,那么您可以省去阅读所有关于“正确”方法的晦涩文档的麻烦。

于 2008-09-30T03:38:03.353 回答
4

尝试OpenRowSet。这可用于导入 Excel 内容。Excel 可以打开 CSV 文件,因此您只需要找出正确的 [ConnectionString][2]。

[2]: Driver={Microsoft 文本驱动程序 (*.txt; *.csv)};Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;

于 2008-09-18T20:24:43.197 回答
3

我知道这不是一个真正的解决方案,但我使用一个虚拟表进行导入,并为所有内容设置了 nvarchar。然后我做了一个插入,它去掉了 " 字符并进行了转换。它不是很漂亮,但它可以完成工作。

于 2008-09-19T05:58:36.700 回答
2

我说使用 FileHelpers 它是一个开源库

于 2008-10-18T18:39:29.123 回答
1

您需要以编程方式执行此操作,还是一次性完成?

使用企业管理器,右键单击导入数据可让您选择分隔符。

于 2008-09-18T20:22:32.513 回答
1

您必须注意 BCP/BULK INSERT,因为如果引用不一致,BSP 或 Bulk Insert 都不能很好地处理这个问题,即使是格式文件(甚至 XML 格式文件也不提供选项)和虚拟 ["] 字符开始和结束并使用 [","] 作为分隔符。从技术上讲,如果没有嵌入的 [,] 字符,CSV 文件不需要有 ["] 字符

正是由于这个原因,逗号分隔的文件有时被称为喜剧限制文件。

OpenRowSet 将需要服务器上的 Excel,并且在 64 位环境中可能会出现问题 - 我知道在 64 位的 Jet 中使用 Excel 会出现问题。

如果文件将来可能与您的期望有所不同,SSIS 确实是您最好的选择。

于 2008-09-18T21:36:09.920 回答
1

如果你愿意,你可以试试这个非常可爱的代码,这将从你的代码中删除不需要的分号。例如,如果您的数据是这样的:
“Kelly”、“Reynold”、“kelly@reynold.com”

Bulk insert test1
from 'c:\1.txt' with ( 
    fieldterminator ='","'
    ,rowterminator='\n')

update test1<br>
set name =Substring (name , 2,len(name))
where name like **' "% '**

update test1
set email=substring(email, 1,len(email)-1)
where email like **' %" '**
于 2008-09-30T03:30:32.903 回答
1

首先您需要将 CSV 文件导入数据表

然后您可以使用 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);
                }
            }
        }
    }
}
于 2013-09-21T03:56:58.823 回答
1

这是一个老问题,所以我写这篇文章是为了帮助任何偶然发现它的人。

SQL Server 2017 引入了 FIELDQUOTE 参数,该参数适用于这个确切的用例。

于 2018-12-11T17:42:37.620 回答
0

是的,K Richard 是对的:FIELDTERMINATOR = '","'

有关详细信息,请参阅http://www.sqlteam.com/article/using-bulk-insert-to-load-a-text-file

于 2008-09-18T20:22:52.030 回答
0

您也可以使用 DTS 或 SSIS。

于 2008-09-18T20:49:58.207 回答
0

您可以控制输入格式吗?| (管道),而 \t 通常是更好的字段终止符。

于 2008-09-18T21:51:29.760 回答
0

如果您弄清楚如何将文件解析为 DataTable,我建议使用 SqlBulkInsert 类将其插入 SQL Server。

于 2008-09-19T06:04:43.957 回答