将CSV文件导入SQL Server

时间:2013-03-06 08:53:42

标签: sql sql-server csv bulkinsert bulk

我正在寻找帮助,使用.csvBULK INSERT文件导入SQL Server,我几乎没有基本问题。

问题:

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

  2. 如果客户端从Excel创建CSV,那么带有逗号的数据将包含在""(双引号)[如下例]中,那么导入如何处理?

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

  4. 以下是带标题的示例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
    )
    

12 个答案:

答案 0 :(得分:141)

基于SQL Server CSV导入

  

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

<强>解决方案

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

  

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

<强>解决方案

如果您正在使用BULK insert,则无法处理双引号,数据将是 用双引号插入行。 将数据插入表后,您可以将这些双引号替换为“”。

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

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

<强>解决方案

要处理因数据或格式无效而未加载到表中的行,可以 使用ERRORFILE property处理,指定错误文件名,它将写入行 错误文件有错误。代码应该看起来像。

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 :(得分:25)

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

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

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

•点击Next >按钮

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

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

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

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

•单击Finish按钮运行包。

上面是website上发现的(我已经使用过并经过测试):

答案 2 :(得分:15)

  

2)如果客户端从excel创建csv,那么具有的数据   逗号括在&#34; ......&#34; (双引号)[如下所示   例子]那么导入如何处理呢?

您应该使用FORMAT =&#39; CSV&#39;,FIELDQUOTE =&#39;&#34;&#39;选项:

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
)

答案 3 :(得分:10)

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

以下是我将如何解决它:

  1. 只需将您的CSV文件保存为Excel中的XLS表(通过这样做,您不必担心分隔符.Excel的电子表格格式将被读作表格并直接导入进入SQL表)

  2. 使用SSIS导入文件

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

  4. 祝你好运。

答案 6 :(得分:1)

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

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

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

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

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


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

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

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

enter image description here

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

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

enter image description here

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

enter image description here

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

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

enter image description here

我建议将其保留为Table或某个自定义+--------+-----------+-------- |Col1 | Col2 |Col3 | |--------+-----------+----------+ |75 | 84 | A | |84 | 68 | B | |75 | 84 | C | |75 | 84 | A | +--------+-----------+----------+ 的名称,以防万一您在导出数据时遇到错误或不确定数据并想进一步分析后再移至您想要的确切表格。

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

答案 7 :(得分:0)

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

enter image description here

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

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

  3.   

    平面文件来源

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

    1. 单击“下一步”并选择最后一个
    2. 选项
        

      SQL客户端

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

      1. 我们可以在CSV中定义表的id(建议将CSV的列调用与表中的字段相同)。在Edit Mappings选项中,我们可以看到每个表的预览以及电子表格的列,如果我们希望向导默认插入id,我们会保留选项未选中。
      2.   

        启用ID插入

        (通常不是从1开始),相反,如果我们在CSV中有一个带有id的列,我们选择启用id插入,下一步是结束向导,我们可以在这里查看更改。

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

        This link has images

答案 8 :(得分:0)

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

MemoryError

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

答案 9 :(得分:0)

我知道答案是可以接受的,但我仍然想分享我的情况,也许可以帮助某人解决他们的问题 工具

  • ASP.NET
  • EF代码优先方法
  • SSMS
  • EXCEL

场景 我正在加载CSV格式的数据集,稍后将其显示在视图中 我尝试使用批量加载,但由于BULK LOAD正在使用

而无法加载
FIELDTERMINATOR = ','

并且Excel单元格也使用, 但是,我也不能直接使用Flat file source,因为我使用的是Code-First Approach,这样做只能在SSMS DB中创建模型,而不能在以后必须使用属性的模型中进行。

解决方案

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

答案 10 :(得分:0)

SSMS: How to import (Copy/Paste) data from excel可能会有所帮助(如果您不想使用BULK INSERT或没有权限)。

答案 11 :(得分:0)

如果您的数据“干净”(没有违反数据约束等),并且您有权将文件放在服务器上,则此处的所有答案都非常有用。如果使用SSMS的内置导入任务,此处提供的一些答案会在第一个错误(PK违规,数据丢失错误等)时停止,并一次给您一个错误。如果您想一次收集所有错误(以防您告诉给您.csv文件的人员以清理其数据),建议您将以下内容作为答案。当您自己“编写” SQL时,此答案还为您提供了完全的灵活性。

注意:我将假设您正在运行Windows操作系统并且可以访问Excel和SSMS。如果没有,我确定您可以调整此答案以满足您的需求。

  1. 使用Excel打开.csv文件。在一个空列中,您将编写一个公式,该公式将构建单个INSERT语句,例如=CONCATENATE("INSERT INTO dbo.MyTable (FirstName, LastName) VALUES ('", A1, "', '", B1,"')", CHAR(10), "GO"),其中A1是具有名字数据的单元格,而A2是具有姓氏数据的单元格。

    • CHAR(10)在最终结果中添加换行符,GO将允许我们运行此INSERT并继续执行下一个,即使有任何错误。
  2. 使用=CONCATENATION()公式突出显示单元格

  3. Shift + End突出显示其余行中的同一列

  4. 在功能区中>主页>编辑>填充>单击向下

    • 这将公式始终应用到表格的下方,因此您不必手动复制粘贴,拖动等操作。可能会向下拖动数千行
  5. Ctrl + C复制已制定的SQL INSERT语句

  6. 粘贴到SSMS

  7. 您可能会注意到,Excel可能会意外地在您的INSERTGO命令的每一个周围加上了双引号。这是从Excel中复制多行值的“功能”(?)。您可以简单地找到"INSERTGO"并将其分别替换为INSERTGO进行清理。

  8. 最后,您准备好运行导入过程

  9. 该过程完成后,检查“消息”窗口中是否有任何错误。您可以选择所有内容(Ctrl + A)并复制到Excel中,并使用列过滤器删除任何成功的消息,然后您将遇到所有错误。

此过程肯定比这里的其他答案要花更长的时间,但是如果您的数据“脏”且充满SQL违规,则您至少可以一次收集所有错误并将其发送给提供数据的人员,如果那是您的情况。