.NET(へたれな)コネタ ADO.NETによるCSVファイル読込

CSVファイルをADO.NETを利用して読込処理を行なったところ、先頭行がヘッダー行とみなされて、読み飛ばされてしまう。という現象にはまりました。ADO.NETの接続プロバイダーの設定等はヘッダーなしのCSVファイルの設定になっているのに、なぜか、その設定が認識されない。

        Dim cn As New OleDb.OleDbConnection
        Dim da As New OleDb.OleDbDataAdapter
        Dim cmd As New OleDb.OleDbCommand
        Dim ds As DataSet
 
        Me.CsvRows = 0
        cn.ConnectionString = _
            "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & UPLOAD_DIR & ";" & _
            "Extended Properties=""text;HDR=NO;FMT=Delimited;"";"
        With cmd
            .CommandText = "Select * From " & pFile
            .Connection = cn
        End With
        da.SelectCommand = cmd
        ds = New DataSet
        da.Fill(ds, "CsvFile")
        cn.Close()

ここでは、「ConnectionString」には正しい接続状態が設定されているが(UPLOAD_DIRにはファイルが保存されているパス名が格納されている)
なぜか、CSVファイルの一行目が無視される。(ちゃんと「HDR=NO」をしているのに!)このとき、「pFile」はファイル名がフルパスにて格納されていた。下記のように「IO.Path.GetFileName(pFile)」でファイル名のみに変更したところ問題解決。

        Dim cn As New OleDb.OleDbConnection
        Dim da As New OleDb.OleDbDataAdapter
        Dim cmd As New OleDb.OleDbCommand
        Dim ds As DataSet
 
        Me.CsvRows = 0
        cn.ConnectionString = _
            "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & UPLOAD_DIR & ";" & _
            "Extended Properties=""text;HDR=NO;FMT=Delimited;"";"
        With cmd
            .CommandText = "Select * From " & IO.Path.GetFileName(pFile)
            .Connection = cn
        End With
        da.SelectCommand = cmd
        ds = New DataSet
        da.Fill(ds, "CsvFile")
        cn.Close()

「CommandText」のSQL文で指定するファイル名は「ConnectionString」で指定した「Data Source」のパス内に存在するファイル名のみで指定する必要があるようです。

プロバイダの設定関係は、文字列で指定するため、バグを検出するのが難しい。これは推測であるが、CommandTextのSQLのFROMファイルをフルパス指定にすると、「ConnectionString」の設定が規定値となってしまうようだ。

In your Microsoft SQL query, specify the name of the text file you want to work with (in this example, PhoneList.csv). Don't specify the entire path name; remember, we've already indicated the folder where the file is stored.

>
だそうです。DB接続プロバイダの「Microsoft.Jet.OLEDB.4.0」はパスを一つのデータベースの空間ととしてエミュレートしているのですね。だから、CommandText のSQL文にはファイル名をテーブルとして記述するのだと痛感しました。このプロバイダの実装者の気持ちになれば当然といえば当然なのですが、せめてエラーとしてあつかって欲しかったですね。