将 CSV 文件导入 SQL Server
Posted
技术标签:
【中文标题】将 CSV 文件导入 SQL Server【英文标题】:Import CSV file into SQL Server 【发布时间】:2013-02-20 23:21:09 【问题描述】:我正在寻求使用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 中。
【参考方案1】:
基于 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/…【参考方案2】:来自 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...
点击下一步>按钮
对于数据源,选择平面文件源。然后使用 Browse 按钮选择 CSV 文件。在单击 下一步 > 按钮之前,请花一些时间配置您希望如何导入数据。
对于目标,选择正确的数据库提供程序(例如,对于 SQL Server 2012,您可以使用 SQL Server Native Client 11.0)。输入服务器名称;勾选Use SQL Server Authentication,输入用户名、密码和数据库,然后点击下一步 > 按钮。
在选择源表和视图窗口中,您可以在单击下一步>按钮之前编辑映射。
选中立即运行复选框并点击下一步>按钮。
点击完成按钮运行包。
【讨论】:
如果您能注明出处the page where you copy/pasted this answer from...,那就太好了 不需要预先创建表,可以在导入过程中创建 我喜欢你只是从一个网页中剪切和粘贴,其中包含非常有用的行“花一些时间配置你希望如何导入数据”。这就是我正在寻找的一切:我似乎根本无法配置它! 哦,“检查使用 SQL Server 身份验证单选按钮” 是错误的,因为您可能非常想使用 Windows 身份验证。哪个适合你。 感谢找到了一步一步的过程,其中包含用于实现上述过程的图像,值得一看:qawithexperts.com/article/sql/…【参考方案3】: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 之后可用。【参考方案4】:解决数据中逗号问题的最佳、最快和最简单的方法是在将 Windows 的列表分隔符设置为逗号以外的其他内容(例如管道)后,使用 Excel 保存逗号分隔文件。然后,这将为您生成一个管道(或其他)分隔文件,然后您可以导入该文件。这被描述为here。
【讨论】:
【参考方案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);
【讨论】:
一个可能对 BulkCopy 类更友好的包装器 busybulkcopy.codeplex.com【参考方案6】:因为他们不使用 SQL 导入向导,所以步骤如下:
在tasks to import数据选项中右击数据库,
向导打开后,我们选择要隐含的数据类型。在这种情况下,它将是
平面文件源
我们选择CSV文件,可以在CSV中配置表格的数据类型,但最好从CSV中带过来。
-
单击“下一步”并在最后一个选项中选择
SQL 客户端
根据我们选择的身份验证类型,一旦完成,就会出现一个非常重要的选项。
-
我们可以在CSV中定义表的id(建议CSV的列和表中的字段名称一样)。在 Edit Mappings 选项中,我们可以看到每个表格的预览以及电子表格的列,如果我们希望向导默认插入 id,我们不选中该选项。
启用 id 插入
(通常不是从 1 开始),如果我们在 CSV 中有一个带有 id 的列,我们选择启用 id 插入,下一步是结束向导,我们可以在这里查看更改。
另一方面,在下面的窗口中可能会出现警报,或警告最好忽略这一点,只有当它们留下错误时才需要注意。
This link has images.
【讨论】:
【参考方案7】:以下是我的解决方法:
只需将您的 CSV 文件另存为 Excel 中的 XLS 工作表(这样做,您不必担心分隔符。Excel 的电子表格格式将作为表格读取并直接导入 SQL 表格)
使用 SSIS 导入文件
在导入管理器中编写自定义脚本以省略/修改您要查找的数据。(或运行主脚本来检查您要删除的数据)
祝你好运。
【讨论】:
投反对票:使用 SSIS 导入 XLS 文件非常糟糕。 SSIS 将尝试猜测 Excel 数据的数据类型,但可能会猜错,您对此无能为力。最好使用 CSV。 好吧,我也建议使用 csv,但如果您阅读过 OP 的场景,他会遇到一些特殊的场景,尤其是分隔符,这对于 xls 工作表来说不是问题。通常,像这样的特殊情况不需要广泛的解决方案,而是需要保留数据的修复程序。在上传文件时,SSIS 允许您选择源表和目标表之间的数据映射,这再次简化了相关工作。这就是为什么建议将此方法作为快速破解的原因。 SSIS 已经可以处理 CSV 文本分隔符。如果您无论如何都在使用 SSIS,那么首先将您的 CSV 保存为 XLS 会让我觉得无缘无故增加了潜在的损坏。 另外,我的 CSV 文件通常对于 Excel 来说太大了。【参考方案8】:我知道这不是上述问题的确切解决方案,但对我来说,当我试图将数据从位于单独服务器上的一个数据库复制到我的本地时,这是一场噩梦。
我试图通过首先将数据从服务器导出到CSV/txt
,然后将其导入到我的本地表中。
两种解决方案:写下查询以导入 CSV
或使用 SSMS 导入数据 向导总是产生错误(错误非常普遍,表示存在解析问题)。虽然我没有做任何特别的事情,只是 export 到 CSV
然后尝试 import CSV
到本地 DB
,错误总是存在.
我试图查看映射部分和数据预览,但总是一团糟。而且我知道主要问题来自 table
列之一,其中包含 JSON
和 SQL
解析器处理错误。
所以最终,我想出了一个不同的解决方案,并想分享它以防其他人遇到类似的问题。
我所做的是在外部服务器上使用了导出向导。
以下是重复相同过程的步骤:
1)右键点击数据库,选择Tasks -> Export Data...
2) 当向导打开时,选择“下一步”,在“数据源:”处选择“SQL Server Native Client”。
如果是外部服务器,您很可能必须为“身份验证模式”选择“使用 SQL Server 身份验证”。
3) 点击Next后,您必须选择Destation。
为此,再次选择“SQL Server Native Client”。
这次你可以提供你本地的(或其他一些外部的DB
)DB
。
4) 点击 Next 按钮后,您有两个选择,要么将整个表从一个 DB
复制到另一个,要么写下查询以指定要复制的确切数据。
就我而言,我不需要整个表(它太大),只需要其中的一部分,所以我选择了“编写查询以指定要传输的数据”。
我建议在使用向导之前在单独的查询编辑器上写下并测试查询。
5) 最后,您需要指定选择数据的目标表。
我建议将其保留为
[dbo].[Query]
或一些自定义的Table
名称,以防您在导出数据时遇到错误,或者如果您不确定数据并希望在移动到您的确切表格之前进一步分析它想要。
现在点击下一步/完成按钮直接进入向导的末尾。
【讨论】:
【参考方案9】:如果您的数据是“干净的”(没有违反数据约束等)并且您有权将文件放在服务器上,那么这里的所有答案都非常有用。如果使用 SSMS 的内置导入任务,此处提供的一些答案会在第一个错误(PK 违规、数据丢失错误等)处停止,并一次给您一个错误。如果你想一次收集所有错误(如果你想告诉给你 .csv 文件的人清理他们的数据),我推荐以下作为答案。当您自己“编写” SQL 时,此答案还为您提供了完全的灵活性。
注意:我假设您运行的是 Windows 操作系统并且可以访问 Excel 和 SSMS。如果没有,我相信您可以调整此答案以满足您的需求。
使用 Excel 打开您的 .csv 文件。在一个空列中,您将编写一个公式,该公式将构建单个 INSERT
statements,例如 =CONCATENATE("INSERT INTO dbo.MyTable (FirstName, LastName) VALUES ('", A1, "', '", B1,"')", CHAR(10), "GO")
,其中 A1 是包含名字数据的单元格,而 A2 具有姓氏数据。
CHAR(10)
在最终结果中添加一个换行符,GO
将允许我们运行此 INSERT
并继续下一个,即使有任何错误。
使用=CONCATENATION()
公式突出显示单元格
Shift + End 突出显示其余行中的同一列
在功能区 > 主页 > 编辑 > 填充 > 单击向下
这会将公式一直应用到工作表中,因此您不必手动复制粘贴、拖动等数千行Ctrl+C复制制定的SQLINSERT
语句
粘贴到 SSMS
您可能会注意到 Excel 可能会在您的每个 INSERT
和 GO
命令周围添加双引号。这是从 Excel 中复制多行值的“功能”(?)。您可以简单地找到 "INSERT
和 GO"
并将其分别替换为 INSERT
和 GO
以进行清理。
终于可以运行导入过程了
该过程完成后,检查消息窗口是否有任何错误。您可以选择所有内容 (Ctrl + A) 并复制到 Excel 中,然后使用列过滤器删除任何成功的消息,然后留下所有错误。
这个过程肯定会比这里的其他答案花费更长的时间,但是如果您的数据“脏”并且充满 SQL 违规,您至少可以一次收集所有错误并将它们发送给给您数据的人,如果这是您的情况。
【讨论】:
【参考方案10】:如上所述,您需要添加 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 或文件存储的方法。
【讨论】:
【参考方案11】:通过首先打开 excel,然后转到 DATA,从 TXT 文件导入,选择将保留 0 前缀值的 csv 扩展名,并将该列另存为 TEXT,因为 excel 将删除前导 0,否则将文件导入 Excel(DO如果您在以 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 版本似乎不支持该功能
【讨论】:
【参考方案12】:我知道有公认的答案,但我仍然想分享我的场景,也许可以帮助某人解决他们的问题 工具
ASP.NET EF 代码优先方法 SSMS Excel场景
我正在加载 CSV 格式的数据集,稍后将显示在视图上
我尝试使用批量加载,但我无法加载 BULK LOAD
正在使用
FIELDTERMINATOR = ','
Excel 单元格也在使用,
但是,我也不能直接使用Flat file source
,因为我使用的是Code-First Approach
,这样做只会在SSMS DB中创建模型,而不是在我以后必须使用属性的模型中。
解决方案
-
我使用平面文件源并从 CSV 文件制作 DB 表(在 SSMS 中右键单击 DB -> 导入平面文件 -> 选择 CSV 路径并按照指示进行所有设置)
在 Visual Studio 中创建模型类(您必须保持所有数据类型和名称与在 sql 中加载的 CSV 文件相同)
在 NuGet 包控制台中使用
Add-Migration
更新数据库
【讨论】:
以上是关于将 CSV 文件导入 SQL Server的主要内容,如果未能解决你的问题,请参考以下文章
如何将csv文件导入到BUIK INSERT以外的sql server表中