223

我正在寻求帮助以.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
)
4

13 回答 13

195

基于 SQL Server CSV 导入

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

解决方案

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

2) 如果客户端从 excel 创建 csv,则带有逗号的数据包含在" ... "(双引号)内 [如下例] 那么导入如何处理这个问题?

解决方案

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

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
    )
于 2013-03-06T09:45:04.913 回答
45

如何使用 SQL Server Management Studio 将 CSV 文件导入数据库,从 2013 年 11 月 5 日开始:

首先在您的数据库中创建一个表,您将向其中导入 CSV 文件。创建表后:

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

  • 右键单击您的数据库并选择任务 -> 导入数据...

  • 单击下一步 >按钮

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

  • 对于目标,选择正确的数据库提供程序(例如,对于 SQL Server 2012,您可以使用 SQL Server Native Client 11.0)。输入服务器名称;选中Use SQL Server Authentication,输入User namePasswordDatabase,然后单击Next >按钮。

  • 在 Select Source Tables and Views 窗口中,您可以在单击Next >按钮之前编辑映射。

  • 选中立即运行复选框,然后单击下一步 >按钮。

  • 单击“完成”按钮运行包。

于 2016-02-12T14:39:17.763 回答
30

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
)
于 2018-01-23T09:11:10.573 回答
15

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

于 2013-11-07T16:45:24.690 回答
5

首先您需要将 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-08-30T04:33:06.777 回答
5

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

在此处输入图像描述

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

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

平面文件源

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

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

SQL 客户端

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

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

启用 id 插入

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

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

这个链接有图片

于 2018-04-11T16:39:21.037 回答
3

这是我将如何解决它:

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

  2. 使用 SSIS 导入文件

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

祝你好运。

于 2017-03-17T18:39:35.620 回答
2

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

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

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

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

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


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

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

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

在此处输入图像描述

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

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

在此处输入图像描述

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

在此处输入图像描述

我建议在使用 Wizard 之前在单独的查询编辑器上写下并测试查询。

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

在此处输入图像描述

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

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

于 2020-04-06T12:02:13.403 回答
2

如果您的数据是“干净的”(没有违反数据约束等)并且您有权将文件放在服务器上,那么这里的所有答案都非常有用。如果使用 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 复制制定的 SQLINSERT语句

  6. 粘贴到 SSMS

  7. INSERT您会注意到 Excel 可能出乎意料地在您的每个和GO命令周围添加了双引号。这是从 Excel 中复制多行值的“功能”(?) 。您可以简单地找到并替换"INSERTGO"替换INSERTGO分别清理它。

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

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

这个过程肯定会比这里的其他答案花费更长的时间,但是如果你的数据是“脏的”并且充满了 SQL 违规,你至少可以一次收集所有错误并将它们发送给给你数据的人,如果那样的话是你的情景。

于 2020-07-24T15:33:06.523 回答
1

如上所述,您需要添加 FORMAT 和 FIELDQUOTE 选项以将 .CSV 数据批量插入 SQL Server。对于您的情况,SQL 语句将如下所示:

BULK INSERT SchoolsTemp
FROM 'C:\CSVData\Schools.csv'
WITH
(
    FORMAT = 'CSV', 
    FIELDQUOTE = '""',
    FIRSTROW = 2,
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n',
    TABLOCK
)

尽管BULK INSERT在 SSMS 中非常适合一次性导入工作,但根据您的用例,您可能需要 SSMS 中的其他选项或使用第 3 方。是一份详细指南,描述了将 CSV 文件导入 SQL Server 的各种选项,包括自动化(我的意思是安排)该过程并为 CSV 位置指定 FTP 或文件存储的方法。

于 2021-11-08T16:37:06.400 回答
0

将文件导入 Excel,首先打开 excel,然后转到 DATA,从 TXT 文件导入,选择将保留 0 前缀值的 csv 扩展名,并将该列另存为 TEXT,否则 excel 将删除前导 0(请勿双击如果您在以 0 [零] 开头的字段中有数字数据,则使用 E​​xcel 打开)。然后只需保存为制表符分隔的文本文件。当您导入 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 版本似乎不支持它

于 2019-02-16T17:59:07.033 回答
0

我知道有公认的答案,但我仍然想分享我的场景,也许可以帮助某人解决他们的 问题

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

场景 我正在加载 CSV 格式的数据集,该数据集后来显示在视图上我尝试使用批量加载,但我无法像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. 更新数据库
于 2019-10-31T15:23:15.400 回答
0

也许不完全是您要问的,但另一种选择是使用Notepad++ 的 CSV Lint 插件

该插件可以预先验证 csv 数据,这意味着检查错误数据,例如缺少引号、不正确的小数分隔符、日期时间格式错误等。并且BULK INSERT可以将 csv 文件转换为 SQL 插入脚本。

在此处输入图像描述

SQL 脚本将包含INSERT1000 条记录的每个 csv 行的语句,并调整任何日期时间和十进制值。该插件会自动检测 csv 中的数据类型,并且它会CREATE TABLE为每列包含一个具有正确数据类型的部分。

在此处输入图像描述

于 2022-01-10T16:43:09.723 回答