OleDB,错过了数据的第一个字符

时间:2013-12-17 18:38:12

标签: c# asp.net csv oledb

我有一个用于我维护的ASP.NET应用程序的CSV读取代码。这个ASP.NET网站从3年开始运行良好,使用Ole.JetDB.4.0的CSV读取代码正常运行,除了偶尔有一些超过4K-5K记录的CSV会产生问题。通常问题是随机位置[随机行]的记录错过了它的第一个字符。

CSV文件只是每行的一堆名称和地址,它们是ASNI格式。 CSV是逗号分隔,数据中没有数据“逗号”,现在用单引号或双引号括起字段。此外,它不经常发生,我们使用相同的代码说70K记录上传他们工作正常,但有些时间说在3年内约3-4个文件只有这个问题,我们每天上传一个文件。

对于那些需要我做的人

using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection
    ("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='text;HDR=Yes;FMT=Delimited';Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
{
   string sql_select = "select * from [" + this.FileName + "]";
   System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
   da.SelectCommand = new System.Data.OleDb.OleDbCommand(sql_select, conn);
   DataSet ds = new DataSet();
   // Read the First line of File to know the header
   string[] lines = System.IO.File.ReadAllLines(HttpContext.Current.Server.MapPath("/System/SaleList/") + FileName);
   string header = "";
   if (lines.Length > 0)
      header = lines[0];

   string[] headers = header.Split(',');
   CreateSchema(headers, FileName);
   da.Fill(ds, "ListData");
   DataTable dt = ds.Tables["ListData"];
}

除了提及之外,这段代码工作得很好。我削减了一些不相关的部分,因此可能无法通过复制粘贴工作。

编辑:更多信息

  1. 我尝试将ODBC与Microsoft Text Driver一起使用,然后我将ACE Driver与OleDB一起使用。结果与所有三个驱动器相同。

  2. 如果我交换问题记录,使用前面的行,那些行读得很好,直到下一个问题行[如果多个行在原始文件中有问题],如果那些只是问题行它工作良好。

  3. 所以从上面来看,似乎有些东西会分散角色计数器的注意力,但是如何确保它能够顺利运行仍然是一个小测验。

    编辑2 :我已将此作为错误提交给Microsoft:https://connect.microsoft.com/VisualStudio/feedback/details/811869/oledb-ace-driver-12-jet-4-0-or-odbc-text-driver-all-fail-to-read-data-properly-from-csv-text-file

4 个答案:

答案 0 :(得分:6)

我建议您使用十六进制编辑器检查问题文件 - 检查导致问题的行和紧接在它之前的行。

特别要看行终止符(仅CR / LF?CR?仅限LF?)并查找任何不可打印的字符。

答案 1 :(得分:1)

尝试使用 ACE驱动程序而不是JET(它在x86和x64服务器上可用,JET只有x86!)

using (System.Data.OleDb.OleDbConnection conn 
     = new System.Data.OleDb.OleDbConnection
    ("Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties="Excel 12.0 Xml;HDR=YES";
     Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
 {

答案 2 :(得分:1)

我得到了相同的 OleDB,缺少数据字符问题,请看这里:

enter image description here

  

因为Microsoft.Jet.OLEDB.4.0驱动程序而丢失了字符   试图猜测列数据类型。在我的情况下,它正在治疗   数据为十六进制而非字母数字。

有问题的oledbProviderString:

oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"
{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited\"";

要解决此问题,我添加了TypeGuessRows = 0

oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"  
{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited;TypeGuessRows=0\"";

<强>摄制:

使用以下内容创建Book1.csv文件:

KU88,G6,CC
KU88,F7,CC

如上图所示,逐步完成此代码。

private void button1_Click(object sender, EventArgs e)
{
    string folder = @"G:\Developers\Folder";
    ReproProblem(folder);
}

static string oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited\"";

private void ReproProblem(string folderPath)
{
    using (OleDbConnection oledbConnection = new OleDbConnection(string.Format(oledbProviderString, folderPath)))
    {
        string sqlStatement = "Select * from [Book1.csv]";
        //open the connection
        oledbConnection.Open();
        //Create an OleDbDataAdapter for our connection
        OleDbDataAdapter adapter = new OleDbDataAdapter(sqlStatement, oledbConnection);
        //Create a DataTable and fill it with data
        DataTable table = new DataTable();
        adapter.Fill(table);
        //close the connection
        oledbConnection.Close();
    }
}

答案 3 :(得分:0)

为什么不用这个:

using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection
("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='text;HDR=Yes;FMT=Delimited';Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
        {
           string sql_select = "select * from [" + this.FileName + "]";
           System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
           da.SelectCommand = new System.Data.OleDb.OleDbCommand(sql_select, conn);
           DataSet ds = new DataSet();

           // Read the First line of File to know the header
           string[] lines = System.IO.File.ReadAllLines(HttpContext.Current.Server.MapPath("/System/SaleList/") + FileName);
        DataTable mdt=new DataTable("ListData");
        for (int i = 1; i < lines.Length; i++)
        {
         string[] sep=lines[i].Split(',');
            foreach (var item in sep)
           {
               mdt.Rows.Add(sep);
           }
        }
           string header = "";
           if (lines.Length > 0)
              header = lines[0];

           string[] headers = header.Split(',');
        ds.Tables.Add(mdt);
        CreateSchema(headers, FileName);
        da.Fill(ds, "ListData");
       DataTable dt = mdt;}

我没有调试它。我希望没有问题,但如果有你在这里。

非常感谢