ChatGPT解决这个技术问题 Extra ChatGPT

将 CSV 文件导入 SQL Server

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

问题:

CSV 文件数据之间可能有 , (逗号)(例如:描述),那么如何进行导入处理这些数据?如果客户端从 Excel 创建 CSV,则带有逗号的数据包含在“”(双引号)内 [如下例] 那么导入如何处理这个问题?我们如何跟踪某些行是否有错误数据,哪些导入会跳过? (导入是否会跳过不可导入的行)

这是带有标题的示例 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: How to import (Copy/Paste) data from excel 可以提供帮助(如果您不想使用 BULK NSERT 或没有权限)。
这是题外话,但您的示例 CSV 文件应该可以毫无问题地加载到 MS Access 中。

s
sawa

基于 SQL Server CSV 导入

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

解决方案

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

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

解决方案

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

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:我们可以创建 || Excel中的分隔值文件?因为大约 20% 的源文件是由客户端使用 Excel 创建的。
@Prabhat 您如何将 Excel 文件加载到 SQL Server 中?
这些不是我正在加载的 Excel 文件。客户正在使用 Excel 创建 .CSV 文件(用于我们的应用程序导入的 20% 的源数据)。我在问我们是否使用 Excel 创建 csv 文件,我们怎样才能拥有 ||作为列值分隔符?
该文件必须在服务器上。不在您的本地计算机上。
@Jess 只要权限配置正确,指定的文件可以是 UNC 路径(例如 \\machinename\public):dba.stackexchange.com/questions/44524/…
T
TylerH

来自 How to import a CSV file into a database using SQL Server Management Studio,自 2013 年 11 月 5 日起:

首先在您的数据库中创建一个表,您将向其中导入 CSV 文件。创建表后: 使用 SQL Server Management Studio 登录到您的数据库 右键单击您的数据库并选择 Tasks -> Import Data... 单击 Next > 按钮 对于 Data Source,选择 Flat File Source。然后使用浏览按钮选择 CSV 文件。在单击 Next > 按钮之前,花一些时间配置您希望如何导入数据。对于目标,选择正确的数据库提供程序(例如,对于 SQL Server 2012,您可以使用 SQL Server Native Client 11.0)。输入服务器名称;选中使用 SQL Server 身份验证,输入用户名、密码和数据库,然后单击下一步 > 按钮。在 Select Source Tables and Views 窗口中,您可以在单击 Next > 按钮之前编辑映射。选中立即运行复选框,然后单击下一步 > 按钮。单击“完成”按钮运行包。


如果您将归因于 the page where you copy/pasted this answer from...,那就太好了
不需要预先创建表,可以在导入过程中创建
我喜欢你只是从一个网页上剪切并粘贴了非常有用的行“花一些时间配置你希望如何导入数据”。这就是我正在寻找的一切:我似乎根本无法配置它!
哦,“检查使用 SQL Server 身份验证”单选按钮是错误的,因为您可能很想使用 Windows 身份验证。无论哪种方式适合您。
感谢您找到了一个带有图像的分步程序来实现上述程序,值得一看:qawithexperts.com/article/sql/…
O
Oleg

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
)

请注意,FORMAT 说明符仅在 SQL Server 2017 之后可用。
S
Sachin Kainth

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


B
Burgi

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

https://i.stack.imgur.com/aVKs3.png

右键单击选项任务中的数据库以导入数据,打开向导后,我们选择要隐含的数据类型。在这种情况下,它将是

平面文件源

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

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

SQL 客户端

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

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

启用 id 插入

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

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

This link has images


B
Brad Larson

首先您需要将 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 类更友好的包装器busybulkcopy.codeplex.com
N
Neil

这是我将如何解决它:

只需将您的 CSV 文件保存为 Excel 中的 XLS 表(这样做,您不必担心分隔符。Excel 的电子表格格式将被读取为表格并直接导入 SQL 表)使用 SSIS 导入文件 编写导入管理器中的自定义脚本以省略/修改您要查找的数据。(或运行主脚本来检查您要删除的数据)

祝你好运。


Downvote:使用 SSIS 导入 XLS 文件非常糟糕。 SSIS 将尝试猜测 Excel 数据的数据类型,但可能会猜错,您对此无能为力。最好使用 CSV。
好吧,我也建议使用 csv,但是如果您阅读过 OP 的场景,他会遇到一些特殊的场景,尤其是分隔符,这对于 xls 工作表来说不是问题。通常,像这样的特殊情况不需要广泛的解决方案,而是需要保留数据的修复程序。在上传文件时,SSIS 允许您选择源表和目标表之间的数据映射,这再次减轻了所涉及的工作量。这就是为什么建议将此方法作为快速破解的原因。
SSIS 已经可以处理 CSV 文本分隔符。如果您无论如何都在使用 SSIS,那么首先将您的 CSV 保存为 XLS 会让我觉得无缘无故地增加了潜在的损坏。
另外,我经常有对于 Excel 来说太大的 CSV 文件。
A
Arsen Khachaturyan

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

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

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

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

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

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

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

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

https://i.stack.imgur.com/mKn5w.png

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

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

https://i.stack.imgur.com/6axAM.png

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

https://i.stack.imgur.com/RLKez.png

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

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

https://i.stack.imgur.com/aAmOc.png

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

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


W
William Herrmann

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

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

使用 Excel 打开您的 .csv 文件。在一个空列中,您将编写一个公式来构建单个 INSERT 语句,例如 =CONCATENATE("INSERT INTO dbo.MyTable (FirstName, LastName) VALUES ('", A1, "', '", B1,"')", CHAR (10), "GO") 例如,其中 A1 是具有名字数据的单元格,A2 具有姓氏数据。 CHAR(10) 在最终结果中添加一个换行符,GO 将允许我们运行这个 INSERT 并继续下一个,即使有任何错误。使用 =CONCATENATION() 公式突出显示单元格 Shift + End 以突出显示其余行中的同一列 在功能区 > 主页 > 编辑 > 填充 > 单击向下 这将公式一直应用到工作表的下方,因此您不需要不必手动复制粘贴、拖动等数千行 Ctrl + C 复制制定的 SQL INSERT 语句 粘贴到 SSMS 您会注意到 Excel 可能出乎意料地在每个 INSERT 和 GO 命令周围添加了双引号.这是从 Excel 中复制多行值的“功能”(?)。您可以简单地找到并分别用 INSERT 和 GO 替换“INSERT and GO”来清理它。最后,您已准备好运行导入过程 过程完成后,检查“消息”窗口是否有任何错误。您可以选择所有内容 (Ctrl + A) 并复制到 Excel 中,然后使用列过滤器删除任何成功的消息,然后留下任何和所有错误。

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


S
Steve Yo

将文件导入 Excel,首先打开 excel,然后转到 DATA,从 TXT 文件导入,选择将保留 0 前缀值的 csv 扩展名,并将该列另存为 TEXT,否则 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 版本似乎不支持它


M
Michael Tomar

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

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

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


C
Chameleon

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

ASP.NET

EF 代码优先方法

SSMS

优秀

场景 我正在加载 CSV 格式的数据集,该数据集后来显示在视图上我尝试使用批量加载,但由于 BULK LOAD 正在使用我无法加载

FIELDTERMINATOR = ','

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

解决方案

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


B
BdR

可能不完全符合您的要求,但另一种选择是使用 CSV Lint plug-in for Notepad++

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

https://i.stack.imgur.com/HIPEf.png

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

https://i.stack.imgur.com/vmyre.png