将CSV文件导入SQL Server


185

我正在寻找使用导入.csv文件到SQL Server的帮助BULK INSERT,我有几个基本问​​题。

问题:

  1. CSV文件数据,之间(例如:描述)之间可能有(逗号),那么如何进行导入处理这些数据?

  2. 如果客户端从Excel创建CSV,则用逗号括起来的数据""(用双引号引起来)(如下例所示),那么导入如何处理呢?

  3. 我们如何跟踪某些行是否包含不良数据,哪些导入会跳过?(导入会跳过不可导入的行)

这是带标题的示例CSV:

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.

和SQL语句导入:

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
)

可能是SSMS:如何从excel导入(复制/粘贴)数据会有所帮助(如果您不想使用BULK NSERT或没有权限)。
丹尼斯

Answers:


169

基于SQL Server CSV导入

1)CSV文件数据的,中间(例如:描述)之间可能有(逗号),那么如何进行导入处理这些数据?

如果您使用,(逗号)作为分隔符,则无法区分作为字段终止符的逗号和数据中的逗号。我会用不同的FIELDTERMINATOR||。代码看起来像这样,它将完美地处理逗号和单斜杠。

2)如果客户端从excel创建csv,则将逗号分隔的数据括在" ... "(双引号)中(如下例所示),那么导入如何处理呢?

如果您使用的是大容量插入,则无法处理双引号,数据将以双引号插入行中。将数据插入表后,您可以将这些双引号替换为' '。

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

3)我们如何跟踪某些行是否包含不良数据,哪些导入会跳过?(导入会跳过不可导入的行)吗?

要处理由于无效数据或格式而未装入表的行,可以使用ERRORFILE属性进行处理,指定错误文件名,它将有错误的行写入错误文件。代码看起来像。

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
    )

1
谢谢您的帮助。注册解决方案1:我们可以创建||吗?从Excel分离值文件?因为大约20%的源文件是由客户端使用Excel创建的。
2013年

@Prabhat如何将Excel文件加载到SQL Server?
Vishwanath Dalvi

这些不是我正在加载的Excel文件。客户端正在使用Excel创建.CSV文件(用于应用程序导入的源数据的20%)。我问我们是否要使用Excel创建csv文件?作为列值分隔符?
Prabhat

如果您对客户端如何从Excel创建CSV文件有影响,可以教他们如何在Excel中设置分隔符(而且,它不再是用逗号分隔的文件了,而是用竖线(|)分隔,例如,考虑到需要克服的障碍,并且如果您拥有SSIS,我建议您进行检查-SQL Server 2012及更高版本的版本具有非常强大的SSIS设计器(在VS 2012及更高版本中)使您的客户端只需发送给您的Excel文件,而不是CSV。
qxotk

我不确定这是否完全正确。您可以在SQL批量插入中处理双引号。此主题上有一个堆栈溢出问题,可以使用格式文件来教批量插入各种定义符。stackoverflow.com/questions/25726385/... advancesharp.com/blog/1083/...
DtechNet

33

首先,您需要在数据库中创建一个表,将在其中导入CSV文件。创建表后,请按照以下步骤操作。

•使用SQL Server Management Studio登录数据库

•右键单击数据库,然后选择 Tasks -> Import Data...

•单击Next >按钮

•对于数据源,选择Flat File Source。然后使用浏览按钮选择CSV文件。在单击Next >按钮之前,花一些时间配置要如何导入数据。

•对于“目标”,选择正确的数据库提供程序(例如,对于SQL Server 2012,可以使用SQL Server Native Client 11.0)。输入服务器名称。检查Use SQL Server Authentication单选按钮。在单击Next >按钮之前,输入用户名,密码和数据库。

•在“选择源表和视图”窗口中,可以在单击Next >按钮之前编辑映射。

•选中Run immediately复选框,然后单击Next >按钮。

•单击Finish按钮运行软件包。

以上内容是在此网站找到的(我已经使用并测试过):


30

1
不必预先创建表,可以在导入过程中创建表
bside 18'Dec

1
我喜欢您只是从网页上剪切并粘贴了非常有用的一行“花一些时间来配置要如何导入数据”。这就是我想要的一切:我似乎根本无法配置它!
Auspex

哦,“检查使用SQL Server身份验证单选按钮”是错误的,因为您可能很想使用Windows身份验证。无论哪种方式都适合您。
Auspex

由于发现图像的分步程序执行上述步骤,值得一看:qawithexperts.com/article/sql/...
user3559462

23

2)如果客户端从excel创建csv,则具有逗号的数据将包含在“ ...”(双引号)中(如下例所示),那么导入如何处理呢?

您应该使用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
)

1
请注意,FORMAT说明符仅自SQL Server 2017起可用
。– kristianp

13

解决数据问题中逗号的最好,最快和最简单的方法是,在将Windows的列表分隔符设置设置为逗号(例如管道)以外的其他内容之后,使用Excel保存逗号分隔的文件。然后将为您生成一个管道(或其他)分隔的文件,然后可以将其导入。这在这里描述。


4

您需要将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);
                }
            }
        }
    }
}

BulkCopy类周围可能更人性化的包装wrapperbulkcopy.codeplex.com
busytools 2015年

3

这是我要解决的方法:

  1. 只需在excel中将CSV文件另存为XLS工作表(这样做,您就不必担心定界符。Excel的电子表格格式将作为表读取,并直接导入到SQL表中)

  2. 使用SSIS导入文件

  3. 在导入管理器中编写一个自定义脚本以省略/修改您要查找的数据(或运行主脚本来仔细检查您要删除的数据)

祝好运。


3
Downvote:用SSIS导入XLS文件很糟糕。SSIS将尝试猜测Excel数据的数据类型,但可能会猜错,您对此无能为力。使用CSV更好。
NReilingh'7

好吧,我也建议使用csv,但是如果您已阅读过OP的方案,则他会有一些特殊的方案,尤其是使用定界符时,这在xls工作表中不是问题。通常,像这样的特殊情况场景不需要广泛的解决方案,而需要保留数据的修复程序。上载文件时,SSIS允许您选择源表和目标表之间的数据映射,这又可以减轻工作量。这就是为什么建议将此方法作为一种快速技巧。
Zee

1
SSIS已经可以处理CSV文本定界符。无论如何,如果您使用的是SSIS,首先将CSV保存为XLS的麻烦就无济于事,因为这会增加潜在的损坏。
NReilingh

另外,我通常对Excel来说CSV文件太大。
Auspex

3

因为他们不使用SQL导入向导,所以步骤如下:

在此处输入图片说明

  1. 在选项任务中右键单击数据库以导入数据,

  2. 打开向导后,我们选择要隐含的数据类型。在这种情况下,

平面文件源

我们选择了CSV文件,您可以在CSV中配置表格的数据类型,但是最好从CSV中获取它。

  1. 单击下一步,然后在最后一个选项中进行选择

SQL客户端

根据身份验证的类型,我们选择它,一旦完成,就会出现一个非常重要的选项。

  1. 我们可以在CSV中定义表格的ID(建议将CSV的列称为表格中的字段)。在选项Edit Mappings中,我们可以在电子表格的列中看到每个表的预览,如果我们希望向导默认情况下插入ID,请取消选中该选项。

启用ID插入

(通常不是从1开始),而是如果在CSV中有一列带有ID的列,则选择启用ID插入,下一步是结束向导,我们可以在此处查看更改。

另一方面,在以下窗口中可能会出现警报或警告,理想的情况是忽略此,只有当它们留下错误时才需要注意。

此链接包含图像


0

首先打开excel,然后将其导入DATA,从TXT File导入,选择将保留0个前缀值的csv扩展名,然后将该列另存为TEXT,以将文件导入到Excel中,因为excel会删除前导0,否则(请不要双击如果您在以0 [零]开头的字段中包含数字数据,则可以使用Excel打开)。然后只需另存为制表符分隔文本文件即可。当您导入到excel中时,您可以选择另存为GENERAL,TEXT等。选择TEXT,这样还可以保留诸如YourCompany,LLC之类的字段中字符串中间的引号。

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

我希望可以使用FORMAT和Fieldquote功能,但是我的SSMS版本似乎不支持该功能


0

我知道,有公认的答案,但仍然,我想分享我的方案,也许帮助别人解决他们的问题 TOOLS

  • ASP.NET
  • EF代码优先方法
  • 短信服务
  • 卓越

SCENARIO 我正在加载CSV格式的数据集,后来将其显示在View上,我试图使用批量加载,但无法像BULK LOAD以前那样加载

FIELDTERMINATOR = ','

Excel单元格也正在使用,, 但是我也不能Flat file source直接使用,因为我正在使用Code-First Approach并仅在SSMS DB中创建模型,而不是在以后不得不使用属性的模型中。

  1. 我使用了平面文件源,并从CSV文件制作了数据库表(在SSMS中右键单击数据库->导入平面文件->选择CSV路径,并按照指示进行所有设置
  2. 在Visual Studio中制作模型类(必须保留所有数据类型和名称,使其与sql中加载的CSV文件的名称相同)
  3. 使用Add-Migration在NuGet包控制台
  4. 更新数据库

0

我知道这不是上述问题的确切解决方案,但是对我来说,当我尝试数据从位于单独服务器上的一个数据库复制到本地时,这是一场噩梦。

我试图通过首先数据从服务器导出CSV/txt然后再将其导入到本地表中来做到这一点。

两种解决方案:写下要导入的查询CSV或使用SSMS 导入数据向导始终会产生错误(错误非常普遍,说明存在解析问题)。尽管我并没有做任何特别的事情,但是只要导出到本地CSV然后尝试导入 CSV到本地DB,错误总是存在的。

我试图查看映射部分和数据预览,但总是一团糟。而且我知道主要的问题来自一table列,其中包含一列,JSONSQL解析器对该列的处理错误。

所以最终,我想出了一个不同的解决方案,并希望共享它,以防其他人遇到类似的问题。


我所做的是,我已经在外部服务器上使用了导出向导

以下是重复相同过程的步骤:
1)右键单击数据库,然后选择Tasks -> Export Data...

2)打开向导后,选择“下一步”,然后在“数据源:”的位置选择“ SQL Server Native Client”。

在此处输入图片说明

如果是外部服务器,则很可能必须为“身份验证模式:”选择“使用SQL Server身份验证”。

3)点击下一步后,您必须选择目标
为此,再次选择“ SQL Server Native Client”。
这次,您可以提供本地(或其他一些外部DBDB

在此处输入图片说明

4)单击“下一步”按钮后,您有两个选择,可以将整个表从一个表复制DB到另一个表,也可以写下查询以指定要复制的确切数据。就我而言,我不需要整个表(它太大了),而只需要其中的一部分,所以我选择了“写查询以指定要传输的数据”。

在此处输入图片说明

我建议在移至向导之前,在单独的查询编辑器上写下并测试查询。

5)最后,您需要指定将要选择数据的目标表。

在此处输入图片说明

如果您在导出数据时遇到错误,或者不确定数据并希望在移至所需的确切表之前进行进一步分析,则建议将其保留为[dbo].[Query]或自定义Table名称。

现在,通过单击下一步/完成按钮直接进入向导的结尾。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.