简体   繁体   English

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

[英]How to import csv file to mssql express server in C# and changing datatypes

I've got a console application that uses an API to get data which is then saved into a csv file in the following format:我有一个控制台应用程序,它使用 API 获取数据,然后按以下格式将数据保存到 csv 文件中:

Headers: TicketID,TicketTitle,TicketStatus,CustomerName,TechnicianFullName,TicketResolvedDate标头: TicketID,TicketTitle,TicketStatus,CustomerName,TechnicianFullName,TicketResolvedDate

Body: String values.正文:字符串值。 where TicketResolvedDate is written as: YYYY-MM-DDTHH:mm:ssZ其中TicketResolvedDate写为: YYYY-MM-DDTHH:mm:ssZ

Now I want to import this csv file into my mssql express database using the same console application and make sure the TicketID is imported as a integer datatype and the TicketResolvedDate as a SQL datetime datatype.现在,我想使用相同的控制台应用程序将此 csv 文件导入到我的 mssql express 数据库中,并确保将TicketID作为 integer 数据类型导入,并将TicketResolvedDate作为 SQL 日期时间数据类型导入。

I've made the following code:我做了以下代码:

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);
}

But I'm not sure if this is remotely near the idea i should have to establish this但我不确定这是否离我应该建立这个的想法很远

You're on the right track, but there are a couple issues with your code.您走在正确的轨道上,但是您的代码存在一些问题。 You're reading the CSV data into objects, but then passing the CsvReader to the bulk copy operation.您正在将 CSV 数据读入对象,然后将 CsvReader 传递给批量复制操作。 At that point all the CSV data in the reader has already been consumed, because you read it all when you were creating objects.此时reader中的CSV数据已经全部消费完了,因为你在创建对象的时候就把它全部读取了。 Thus the SqlBulkCopy won't see any data in the reader.因此 SqlBulkCopy 不会在读取器中看到任何数据。

The next issue that I think you're going to have is that the "schema" of the data reader needs to match the schema of the target SQL table.我认为您将遇到的下一个问题是数据读取器的“架构”需要与目标 SQL 表的架构相匹配。 If the schemas don't match, you'll typically get some cryptic error message out of the SqlBulkCopy operation, that some type can't be converted.如果模式不匹配,您通常会从 SqlBulkCopy 操作中得到一些神秘的错误消息,即无法转换某些类型。

I maintain a library that I've specifically designed to work well in this scenario: Sylvan.Data.Csv .我维护了一个专门设计用于在这种情况下正常工作的库: Sylvan.Data.Csv It allows you to apply a schema to the "untyped" CSV data.它允许您将模式应用于“未类型化”的 CSV 数据。

Here is an example of how you could write CSV data to a table in SqlServer:以下是如何将 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);
}

You still might encounter errors if the CSV data doesn't correctly match the schema, or has invalid or broken records, but this should work if your csv files are clean and valid.如果 CSV 数据与模式不正确匹配,或者有无效或损坏的记录,您仍然可能会遇到错误,但如果您的 csv 文件干净且有效,这应该会起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM