如何在C#中将csv文件导入mssql express服务器并更改数据类型

6l7fqoea  于 2023-01-28  发布在  C#
关注(0)|答案(1)|浏览(123)

我有一个控制台应用程序,它使用API获取数据,然后以以下格式保存到csv文件中:
顶盖:TicketID,TicketTitle,TicketStatus,CustomerName,TechnicianFullName,TicketResolvedDate
正文:字符串值。其中TicketResolvedDate的写法为:YYYY-MM-DDTHH:mm:ssZ
现在,我想使用相同的控制台应用程序将此csv文件导入到mssql express数据库中,并确保TicketID作为整数数据类型导入,TicketResolvedDate作为SQL日期时间数据类型导入。
我已经做了下面的代码:

List<TicketCSV> tickets = new List<TicketCSV>();

using var reader1 = new StreamReader(OutputClosedTickets);
using var reader2 = new StreamReader(OutputWorkhours);

using var csv1 = new CsvReader((IParser)reader1);
{
    csv1.Configuration.Delimiter = ",";
    csv1.Configuration.MissingFieldFound = null;
    csv1.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();

    csv1.ReadHeader();
    while (csv1.Read())
    {
        var record = new TicketCSV
        {
            TicketID = csv1.GetField<int>("TicketID"),
            TicketTitle = csv1.GetField("TicketTitle"),
            TicketStatus = csv1.GetField("TicketStatus"),
            CustomerName = csv1.GetField("CustomerName"),
            TechnicianFullName = csv1.GetField("TechnicianFullName"),
            TicketResolvedDate = SqlDateTime.Parse(csv1.GetField("TicketResolvedDate"))

        };
        tickets.Add(record);

    }
}

using (var bulkCopy = new SqlBulkCopy(connectionString))
{
    bulkCopy.DestinationTableName = "GeslotenTickets";
    bulkCopy.WriteToServer((IDataReader)csv1);

    bulkCopy.DestinationTableName = "WerkUren";
    bulkCopy.WriteToServer((IDataReader)reader2);
}

但我不确定这是否与我应该建立的想法有一点关系

3b6akqbq

3b6akqbq1#

您的思路是正确的,但您的代码存在一些问题。您将CSV数据读入对象,但随后将CsvReader传递给大容量复制操作。此时,读取器中的所有CSV数据都已用完,因为您在创建对象时读取了所有CSV数据。因此,SqlBulkCopy不会在读取器中看到任何数据。
我认为您将遇到的下一个问题是数据读取器的“schema”需要与目标SQL表的schema匹配。如果schema不匹配,您通常会从SqlBulkCopy操作中得到一些隐含的错误消息,即某些类型无法转换。
我维护了一个专门设计的库,以便在此场景中正常工作:Sylvan.Data.Csv。它允许您将模式应用于“无类型”CSV数据。
下面是如何将CSV数据写入SqlServer中的表的示例:

using Sylvan.Data.Csv;
using System.Data.SqlClient;

static void LoadTableCsv(SqlConnection conn, string tableName, string csvFile)
{

    // read the column schema of the target table
    var cmd = conn.CreateCommand();
    cmd.CommandText = $"select top 0 * from {tableName}"; // beware of sql injection
    var reader = cmd.ExecuteReader();
    var colSchema = reader.GetColumnSchema();
    reader.Close();

    // apply the column schema to the csv reader.
    var csvSchema = new CsvSchema(colSchema);
    var csvOpts = new CsvDataReaderOptions { Schema = csvSchema };
    using var csv = CsvDataReader.Create(csvFile, csvOpts);

    using var bulkCopy = new SqlBulkCopy(conn);
    bulkCopy.DestinationTableName = tableName;
    bulkCopy.EnableStreaming = true;
    bulkCopy.WriteToServer(csv);
}

如果CSV数据与模式不匹配,或者有无效或损坏的记录,您仍然可能遇到错误,但是如果您的csv文件是干净和有效的,这应该可以工作。

相关问题