使用 OleDB 从 CSV 导入行/批次范围
Import range of rows / batches from CSV with OleDB
我想使用 ole db 动态获取 selected 具有特定范围的行,这就是我写的代码:
Dim ConStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TextBox1.Text & ";Extended Properties=""TEXT;HDR=Yes;FMT=Delimited"""
Dim conn As New OleDb.OleDbConnection(ConStr)
Dim dt As New DataTable
Try
Dim CMD As String = "Select * from " & _table & ".csv WHERE ID BETWEEN " & min & "AND " & max
Dim da As New OleDb.OleDbDataAdapter(CMD, conn)
da.Fill(dt)
它在一个带有 max 和 min 的 for 循环中运行,一步一步地获取行并将它们传递给另一个函数,但问题是上面的代码并没有真正起作用,因为它会照看 ID 但它实际上应该照顾行。我的意思是有 70.000 行但有 200.000 个 ID。我如何在 oledb 中 select 行?
如果我理解你的问题,你可以像下面那样使用 OLEDB select 单元格范围。
Select * from [Sheet1$A1:B10]
从根本上说,除非偶然,否则 ID 与行数没有任何关系。 DataAdapter.Fill()
方法有一个重载,可让您 指定加载的行范围 。我仔细检查以确保它适用于 OleDB 文本驱动程序。
Private OLECSVConnstr = ...your text driver connection string
Private firstRow As Int32 = 0
Private rowCount As Int32 = 1000
...
Private Function ImportRows(csvFile As String) As Int32
Dim SQL = String.Format("SELECT * FROM {0}", csvFile)
Dim rows As Int32
Using dbcon As New OleDbConnection(OLECSVConnstr)
Using cmd As New OleDbCommand(SQL, dbcon)
' DataTable is IDiposable, so dont just
' (re)create a new one each time
If dtSample Is Nothing Then
dtSample = New DataTable
Else
dtSample.Rows.Clear()
End If
Using da As New OleDbDataAdapter(cmd)
dbcon.Open()
rows = da.Fill(firstRow, rowCount, dtSample)
End Using
' increment firstrow for next time
firstRow += rowCount
End Using
End Using
dgv2.DataSource = dtSample
Return rows
End Function
编辑: 由于 DataTable
实现 IDisposable
为每个 "batch"/行集创建一个新的可能会导致泄漏。如果需要,以上检查并创建一个新行,否则清除行。或者,您可以只创建一次 DataAdapter。
DataAdapter.Fill(int first, int count, DataTable dt)
允许您告诉适配器要加载的第一行以及加载的行数。上面的 ImportRows
方法 returns 实际加载了多少行,所以当它 returns 少于请求的数量时,应该意味着没有更多的行。
对于这么大的文件,我会使用带有 OleDB 文本驱动程序的 Schema.INI
,这样您就可以指定用于每一行的数据类型。没有它,文本驱动程序会根据前几行中的数据确定数据类型(猜测)。
我应该提到 CSVHelper
也可以用于批量加载行。它在您调用 Read()
时一次读取 CSV 一行,因此您所要做的就是维护对 CSV reader 的引用并在循环中调用它以一次获取 N 行时间。
我想使用 ole db 动态获取 selected 具有特定范围的行,这就是我写的代码:
Dim ConStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TextBox1.Text & ";Extended Properties=""TEXT;HDR=Yes;FMT=Delimited"""
Dim conn As New OleDb.OleDbConnection(ConStr)
Dim dt As New DataTable
Try
Dim CMD As String = "Select * from " & _table & ".csv WHERE ID BETWEEN " & min & "AND " & max
Dim da As New OleDb.OleDbDataAdapter(CMD, conn)
da.Fill(dt)
它在一个带有 max 和 min 的 for 循环中运行,一步一步地获取行并将它们传递给另一个函数,但问题是上面的代码并没有真正起作用,因为它会照看 ID 但它实际上应该照顾行。我的意思是有 70.000 行但有 200.000 个 ID。我如何在 oledb 中 select 行?
如果我理解你的问题,你可以像下面那样使用 OLEDB select 单元格范围。
Select * from [Sheet1$A1:B10]
从根本上说,除非偶然,否则 ID 与行数没有任何关系。 DataAdapter.Fill()
方法有一个重载,可让您 指定加载的行范围 。我仔细检查以确保它适用于 OleDB 文本驱动程序。
Private OLECSVConnstr = ...your text driver connection string
Private firstRow As Int32 = 0
Private rowCount As Int32 = 1000
...
Private Function ImportRows(csvFile As String) As Int32
Dim SQL = String.Format("SELECT * FROM {0}", csvFile)
Dim rows As Int32
Using dbcon As New OleDbConnection(OLECSVConnstr)
Using cmd As New OleDbCommand(SQL, dbcon)
' DataTable is IDiposable, so dont just
' (re)create a new one each time
If dtSample Is Nothing Then
dtSample = New DataTable
Else
dtSample.Rows.Clear()
End If
Using da As New OleDbDataAdapter(cmd)
dbcon.Open()
rows = da.Fill(firstRow, rowCount, dtSample)
End Using
' increment firstrow for next time
firstRow += rowCount
End Using
End Using
dgv2.DataSource = dtSample
Return rows
End Function
编辑: 由于 DataTable
实现 IDisposable
为每个 "batch"/行集创建一个新的可能会导致泄漏。如果需要,以上检查并创建一个新行,否则清除行。或者,您可以只创建一次 DataAdapter。
DataAdapter.Fill(int first, int count, DataTable dt)
允许您告诉适配器要加载的第一行以及加载的行数。上面的 ImportRows
方法 returns 实际加载了多少行,所以当它 returns 少于请求的数量时,应该意味着没有更多的行。
对于这么大的文件,我会使用带有 OleDB 文本驱动程序的 Schema.INI
,这样您就可以指定用于每一行的数据类型。没有它,文本驱动程序会根据前几行中的数据确定数据类型(猜测)。
我应该提到 CSVHelper
也可以用于批量加载行。它在您调用 Read()
时一次读取 CSV 一行,因此您所要做的就是维护对 CSV reader 的引用并在循环中调用它以一次获取 N 行时间。