即使在连接字符串中使用 HDR=No ,使用 OLEDB 读取 CSV 文件也会忽略第一行

Posted

技术标签:

【中文标题】即使在连接字符串中使用 HDR=No ,使用 OLEDB 读取 CSV 文件也会忽略第一行【英文标题】:Reading CSV file with OLEDB ignores first line even with HDR=No in Connection String 【发布时间】:2011-01-04 19:39:11 【问题描述】:

我们正在将经典 ASP 网站转换为 ASP.NET 网站。一项功能是以 CSV 格式上传数据的“模板”,以便导入数据库。那里有几种不同的记录类型(第一个字段总是标识数据的类型)。

任务是将 CSV 放入 DataTable 以便对其进行验证(新项目是拥有更好的验证规则)

代码看起来很简单 - 淡化(取出 cmets、Try/Catch 等)如下:

    Dim da As New System.Data.OleDb.OleDbDataAdapter
    Dim cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDirectory & ";" & "Extended Properties=""Text;HDR=No;FMT=Delimited;""")
    Dim cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & strCSVFilename, cn)
    cn.Open()
    da.SelectCommand = cd
    da.Fill(dtData)

DataTable (dtData) 已填充,但仅从 CSV 文件的第二行开始,尽管“HDR=No”在连接字符串中。

我在这里错过了什么?

【问题讨论】:

如下所示,如果 strCSVFilename 中有路径,无论出于何种原因,它将第一行视为标题行。如果它只有文件名(并且连接字符串会告诉 ADO 使用什么路径),第一行将被导入数据表中。 对我不起作用。数据源有路径,SELECT 语句只有文件名。 HDR=NO 但第一行的字段正在成为列标题。 【参考方案1】:

文件开头是否有某些内容导致第一行被跳过?也许是不可打印的字符? NPC 可能来自未以预期编码保存的文件。当我创建一个 CSV 文件时,我收到了您期望的结果。这是我用来测试的代码:

    Private Sub Test()
    Dim TempDir = My.Computer.FileSystem.SpecialDirectories.Temp
    Dim TempFile = "Test.csv"

    '//Create our test file with a header row and three data rows
    Using FS As New System.IO.FileStream(System.IO.Path.Combine(TempDir, TempFile), IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Read)
        Using SW As New System.IO.StreamWriter(FS, System.Text.Encoding.ASCII)
            SW.WriteLine("Col1,Col2")
            SW.WriteLine("R1", "R1")
            SW.WriteLine("R2", "R2")
            SW.WriteLine("R3", "R3")
        End Using
    End Using

    '//Read the data into a table specifying that the first row should be treated as a header
    Using dtData As New DataTable()
        Using da As New System.Data.OleDb.OleDbDataAdapter
            Using cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TempDir & ";" & "Extended Properties=""Text;HDR=Yes;FMT=Delimited;""")
                Using cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & TempFile, cn)
                    cn.Open()
                    da.SelectCommand = cd
                    da.Fill(dtData)
                    Trace.WriteLine("With header,    expected 3, found " & dtData.Rows.Count)
                End Using
            End Using
        End Using
    End Using

    '//Read the data into a table again, this time specifying that the there isn't a header row
    Using dtData As New DataTable()
        Using da As New System.Data.OleDb.OleDbDataAdapter
            Using cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TempDir & ";" & "Extended Properties=""Text;HDR=No;FMT=Delimited;""")
                Using cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & TempFile, cn)
                    cn.Open()
                    da.SelectCommand = cd
                    da.Fill(dtData)
                    Trace.WriteLine("Without header, expected 4, found " & dtData.Rows.Count)
                End Using
            End Using
        End Using
    End Using

    '//Delete our temporary file
    System.IO.File.Delete(System.IO.Path.Combine(TempDir, TempFile))
End Sub

如果您将初始编码更改为 Unicode,您将在结果中得到 8 行和 9 行,这可能就是您所看到的。如果结果是编码问题,您可以将CharacterSet=Unicode 添加到您的扩展属性中。

【讨论】:

关闭但没有雪茄。原来问题出在我传递给 SELECT * FROM 命令的文件名中。最初,路径在 Connect 字符串和 SELECT 命令中。当我出于某种原因选择 SELECT 命令的路径时,它起作用了。换句话说,“SELECT * FROM Sample.csv”给了我所有的行。 "SELECT * FROM C:\Inetpub\wwwroot\Site\Upload\Sample.csv" 导致第一行被忽略。我会在这个答案上打勾,因为它让我走上了正确的道路。

以上是关于即使在连接字符串中使用 HDR=No ,使用 OLEDB 读取 CSV 文件也会忽略第一行的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jet Oledb 读取文本文件并关闭标题 (HDR=No)

关于OleDB连接Excel的Extended Properties(扩展属性)HDR=YES; IMEX=2个人理解心得

ACE.OLEDB 链接字符串:关于Excel导入的HDR=YES; IMEX=1

ado.net 访问excel

可变宏中令牌的连接

无法绑定多部分标识符“SR_DOC_HDR.DOC_VERS_NO”