c# - 在 C# 中将 CSV 导出到 SQL - 如何将导出偏移一列
问题描述
我正在使用 C# 解析 csv 文件并导出到 SQL Server 数据库表。数据库表的架构几乎与 csv 文件的架构相同,不同之处在于该表有一个主键标识列作为第一列。
问题:数据库表的第2列,应该接收csv 文件的第 1列,实际上是接收 csv 文件的第 2 列。该代码假设数据库表的第一个 PK Identity 列是要从 CSV 文件写入的第一列。万一这令人困惑,假设 CSV 文件的第 1、2 和 3 列分别具有名为Contoso1
、Contoso2
和的标题Contoso3
。数据库表的第 1 到第 4 列分别称为Id
、Contoso1
、Contoso2
和Contoso3
。在导出过程中,该Id
列正确地填充了标识 ID,但随后Contoso1
数据库表的列被填充了Contoso2
CSV 文件的列,并且对于所有 300 列继续关闭一列。
这是代码。我正在寻找一种使用此代码进行单列偏移的方法。如果可能的话,我想避免硬编码映射方案,因为有 300 多列。
using System;
using System.Data.SqlClient;
using System.Data;
using Microsoft.VisualBasic.FileIO;
namespace CSVTest
{
class Program
{
static void Main(string[] args)
{
string csv_file_path = @"pathToCsvFile";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
InsertDataIntoSQLServerUsingSQLBulkCopy(csvData);
}
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
DataTable csvData = new DataTable();
try
{
using (TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
return null;
}
return csvData;
}
static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData)
{
using (SqlConnection dbConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Database_Name;Integrated Security=SSPI;"))
{
dbConnection.Open();
using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
{
s.DestinationTableName = "TableName";
//foreach (var column in csvFileData.Columns)
//s.ColumnMappings.Add(column.ToString(), column.ToString());
s.WriteToServer(csvFileData);
}
}
}
}
}
解决方案
我假设-
一个。只有一列需要跳过,但可以修改为添加多列跳过
湾。你知道,提前,要跳过的列的从零开始的索引。
除此之外,这里是您需要进行的 3 项修改。
- 添加变量以存储要跳过的索引
string csv_file_path = @"pathToCsvFile";
//Assuming just one index for the column number to skip - zero based counting.
//perhaps read from the AppConfig
int columnIndexToSkip = 0;
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path, columnIndexToSkip);
- 修改函数签名以采用额外的 int 参数
private static DataTable GetDataTabletFromCSVFile(string csv_file_path, int columnIndexToSkip)
{
- 在该索引处添加虚拟列
csvData.Rows.Add(fieldData);
}
}// end of while (!csvReader.EndOfData) loop
if (columnIndexToSkip >= 0)
{
csvData.Columns.Add("DUMMY").SetOrdinal(columnIndexToSkip);
}
我没有测试导入,但更新后的 csv 文件对我来说看起来不错。
推荐阅读
- java - 对象字段的Java冒泡排序方法
- laravel - Laravel Eloquent 高级查询
- sql - 插入触发器之前的 SQL 可以访问 INSERT 语句的值吗?
- list - Ansibe Jinja2 过滤器
- c# - 如何在 C# 控制台应用程序中执行 R 脚本?
- nuxt.js - 使用 SSR 时如何防止 Nuxt 水化?
- python - 如何检测在 Python 中打开的文件的每一行中的第一个非空白字符?
- vue.js - 将砌体应用于 vue 网格项目的简单方法?
- mysql - Mysql - Invoice、Invoiceitems 和畅销产品
- oracle - 有没有办法在 Netsuite 保存的搜索中排列具有相同值的行(将它们分组)在其他行下方?