[英]Import CSV file into 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
)
基于 SQL Server CSV 导入
1) CSV 文件数据之间可能有
,
(逗号)(例如:描述),那么我该如何导入处理这些数据?
解决方案
如果您使用,
(逗号)作为分隔符,则无法区分作为字段终止符的逗号和数据中的逗号。 我会使用不同的FIELDTERMINATOR
如||
. 代码看起来像这样,这将完美地处理逗号和单斜杠。
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
)
您首先需要在您的数据库中创建一个表,您将在其中导入 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
按钮运行包。
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
)
解决数据中逗号问题的最佳、最快和最简单的方法是在将 Windows 的列表分隔符设置为逗号以外的其他设置(例如管道)后,使用 Excel 保存逗号分隔的文件。 然后,这将为您生成一个管道(或其他)分隔文件,然后您可以导入该文件。 这在此处进行了描述。
首先需要将 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);
}
}
}
}
}
这是我将如何解决它:
只需将您的 CSV 文件另存为 Excel 中的 XLS 表(这样做,您就不必担心分隔符。Excel 的电子表格格式将被读取为表格并直接导入到 SQL 表格中)
使用 SSIS 导入文件
在导入管理器中编写自定义脚本以省略/修改您要查找的数据。(或运行主脚本来仔细检查您要删除的数据)
祝你好运。
因为他们不使用 SQL 导入向导,所以步骤如下:
右键单击选项任务中的数据库以导入数据,
打开向导后,我们选择要隐含的数据类型。 在这种情况下,它将是
平面文件源
我们选择CSV文件,可以在CSV中配置表格的数据类型,但是最好从CSV中带过来。
SQL客户端
根据我们选择的身份验证类型,一旦完成,就会出现一个非常重要的选项。
启用 ID 插入
(通常不是从 1 开始),相反,如果我们在 CSV 中有一个带有 id 的列,我们选择启用 id 插入,下一步是结束向导,我们可以在这里查看更改。
另一方面,在接下来的窗口中可能会出现alerts,或者warnings,理想的情况是忽略这一点,只有当他们留下error时才需要注意。
我知道这不是上述问题的确切解决方案,但对我来说,当我尝试将数据从位于单独服务器上的一个数据库复制到本地时,这是一场噩梦。
我试图通过首先将数据从服务器导出到CSV/txt
然后将其导入到我的本地表来做到这一点。
两种解决方案:写下导入CSV
的查询或使用 SSMS导入数据向导总是会产生错误(错误非常普遍,表示存在解析问题)。 虽然我没有做任何特别的事情,只是导出到CSV
然后尝试将CSV
导入到本地DB
,但错误总是存在。
我试图查看映射部分和数据预览,但总是有很大的混乱。 而且我知道主要问题来自table
列之一,该列包含JSON
而SQL
解析器错误地处理了该列。
所以最终,我想出了一个不同的解决方案,并希望分享它,以防其他人遇到类似的问题。
我所做的是在外部服务器上使用了导出向导。
以下是重复相同过程的步骤:
1) 右键单击数据库并选择Tasks -> Export Data...
2) 当向导打开时,选择下一步并在“数据源:”的位置选择“SQL Server Native Client”。
对于外部服务器,您很可能必须为“身份验证模式:”选择“使用 SQL Server 身份验证”。
3) 点击Next 后,您必须选择Destination 。
为此,再次选择“SQL Server Native Client”。
这次您可以提供您的本地(或其他一些外部DB
) DB
。
4) 点击下一步按钮后,您有两种选择,要么将整个表从一个DB
复制到另一个DB
,要么写下查询以指定要复制的确切数据。 就我而言,我不需要整个表(它太大),而只需要其中的一部分,因此我选择了“编写查询以指定要传输的数据”。
我建议在移动到向导之前,在单独的查询编辑器上写下并测试查询。
5) 最后,您需要指定将选择数据的目标表。
我建议将其保留为
[dbo].[Query]
或一些自定义Table
名称,以防万一导出数据时出错,或者您不确定数据并希望在移至所需的确切表之前对其进行进一步分析.
现在点击下一步/完成按钮直接进入向导的结尾。
如果您的数据是“干净的”(没有违反数据约束等)并且您有权将文件放在服务器上,那么这里的所有答案都很好用。 如果使用 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 违规,您至少可以一次收集所有错误并将它们发送给提供数据的人,如果是你的场景。
如上所述,您需要添加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 中的其他一些选项或使用 3rd 方。 这是一个详细的指南,描述了将 CSV 文件导入 SQL Server 的各种选项,包括自动化(我的意思是安排)该过程以及为 CSV 位置指定 FTP 或文件存储的方法。
将文件导入 Excel,首先打开 excel,然后转到 DATA,从 TXT 文件导入,选择将保留 0 前缀值的 csv 扩展名,并将该列保存为 TEXT 因为 excel 将删除前导 0 否则(不要双击如果字段中有以 0 [零] 开头的数字数据,则使用 Excel 打开)。 然后保存为制表符分隔的文本文件。 当您导入到 excel 时,您可以选择另存为 GENERAL、TEXT 等。
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 版本中似乎不支持
我知道有公认的答案,但我仍然想分享我的场景,也许可以帮助某人解决他们的问题工具
方案I被加载这是后来在视图中显示哪些是CSV格式的数据集我试图使用大容量负载,但我是无法负荷BULK LOAD
使用
FIELDTERMINATOR = ','
并且 Excel 单元格也在使用,
但是,我也无法直接使用Flat file source
,因为我使用的是Code-First Approach
并且只在 SSMS DB 中制作模型,而不是在我稍后必须从中使用属性的模型中.
解决方案
Add-Migration
可能是SSMS: How to import (Copy/Paste) data from excel可以提供帮助(如果您不想使用BULK INSERT
或没有权限)。
如上所述,您需要添加 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 中的其他一些选项或使用 3rd 方。 这是一个详细的指南,描述了将 CSV 文件导入 SQL Server 的各种选项,包括自动化(我的意思是安排)该过程以及为 CSV 位置指定 FTP 或文件存储的方法。
也许不完全是您要问的,但另一种选择是使用Notepad++的CSV Lint 插件
该插件可以预先验证 csv 数据,这意味着检查错误数据,如缺少引号、不正确的小数分隔符、日期时间格式错误等。它可以将 csv 文件转换为 SQL 插入脚本,而不是BULK INSERT
。
SQL 脚本将包含 1000 条记录的每个 csv 行的INSERT
语句,并调整任何日期时间和十进制值。 该插件会自动检测 csv 中的数据类型,并将包含一个CREATE TABLE
部分,其中包含每列的正确数据类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.