在数据表的列中指定数据类型

时间:2017-05-16 13:48:51

标签: vb.net csv

我试图将人员本地计算机上的CSV文件上传到我的程序中,但我遇到了一些麻烦。我有一列是数字和文本的混合,例如F-23,Pool等。但是,当我上传文件时,它会将该列专门视为十进制列。无论如何我可以将所有列值设置为字符串类型以避免这种情况吗?我现在正在使用Oledb将csv上传到数据表中。

将csv上传到数据表中的代码如下。

Dim conn As OleDbConnection = New 
OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & 
Path.GetDirectoryName(fullDir) & ";Extended 
Properties=""Text;HDR=Yes;FMT=Delimited(,);IMEX=1"";")
conn.Open()
Dim adp As New OleDbDataAdapter("SELECT * FROM [" & fileName & "]", conn)
adp.Fill(dt)
conn.Close()

4 个答案:

答案 0 :(得分:2)

如果您知道列是:

,那么您可以处理这种情况的好方法

让我们在这里使用人事档案的小例子。

1 /使用各自的列

创建
CREATE TABLE My_Personnel(
   ID   INT              NOT NULL,
   NAME VARCHAR (50)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  VARCHAR (1000) ,  
   PRIMARY KEY (ID)
);

然后你会创建一个 Class 来存储这样的数据:

Public Class Person
    Public Property ID As Integer
    Public Property Name As String
    Public Property Age As Integer
    Public Property Address As String
End Class

然后您将创建功能以使用TextFieldParser提取数据:

Imports Microsoft.VisualBasic.FileIO.TextFieldParser

ExtractData 功能:

Public Function ExtractData(ByVal csvData As String) As List(Of Person)
    Dim result As New List(Of Person)
    Dim afile As FileIO.TextFieldParser = New FileIO.TextFieldParser(csvData)
    Dim CurrentRecord As String() ' this array will hold each line of data
    afile.TextFieldType = FileIO.FieldType.Delimited
    afile.Delimiters = New String() {","}
    afile.HasFieldsEnclosedInQuotes = True
    ' parse the actual file
    Do While Not afile.EndOfData
        Try
            Dim tempPerson As New Person
            CurrentRecord = afile.ReadFields
            tempPerson.ID = CurrentRecord(0)
            tempPerson.Name = CurrentRecord(1)
            tempPerson.Age = CurrentRecord(2)
            tempPerson.Address = CurrentRecord(3)
            result.Add(tempPerson)
        Catch ex As FileIO.MalformedLineException
            Stop
        End Try
    Loop
    Return result
End Function

只需致电

Dim MyPersonnel As List(Of Person) = ExtractData("C:\test.csv")

在此之后只需创建一个函数,其中MyPersonnel中的每个Person都将数据插入到数据库中。

仅当您确定数据具有固定格式

时才会有效

这里我使用一个类来存储数据,以防你需要修改它或者如果你需要插入它就可以直接为extract函数中的每一行创建一个插入

答案 1 :(得分:1)

这是我一直使用的功能,你可以通过在for循环中插入if来灵活变通: -

Public Function convert_csv_to_data_table(ByVal File As String, ByVal separator As String)
    Dim dt As New System.Data.DataTable
    Dim firstLine As Boolean = True
    If IO.File.Exists(File) Then
        Using sr As New StreamReader(File)
            While Not sr.EndOfStream
                If firstLine Then
                    firstLine = False
                    Dim cols = sr.ReadLine.Split(separator)
'down here change the cols types (they are all set as string at the moment)
'however you can change by using if's, eg. if col = "field name" then dt.Columns.Add(New DataColumn(col, GetType(DECIMAL))).
                    For Each col In cols
                        dt.Columns.Add(New DataColumn(col, GetType(String)))
                    Next
                Else
                    Dim data() As String = sr.ReadLine.Split(separator)
                    dt.Rows.Add(data.ToArray)
                End If
            End While
        End Using
    End If
    Return dt
End Function

答案 2 :(得分:0)

因此,正如Mederic和Colster先前提到的,我可以简单地使用Schema文件来更改在特定CSV文件上读取值的方式。所以为了做到这一点,知道列在任何上传过程中都保持不变,我创建了一个模式并将列设置为它们各自的值。

Dim strSchema() As String = {"[" & ofdOpenExcelSheet.SafeFileName & "]", "ColNameHeader=True", "Format=CSVDelimited", "Col1=A Text", "Col2=B Text", "Col3=C Text", "Col4=D Text", "Col5=E Integer", "Col6=""F Space"" Decimal", "Col7=""G Space"" Decimal"}
Using outFile As New StreamWriter(Path.GetDirectoryName(fullDir) & Convert.ToString("\Schema.ini"))
    For Each line As String In strSchema
        outFile.WriteLine(line)
    Next
End Using
Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path.GetDirectoryName(fullDir) & ";Extended Properties=""Text;HDR=Yes;FMT=Delimited;MaxScanRows=0;IMEX=1"";")
conn.Open()
Dim adp As New OleDbDataAdapter("SELECT * FROM [" & fileName & "]", conn)
adp.Fill(dt)
conn.Close()
' Remove schema since we don't need it.
My.Computer.FileSystem.DeleteFile(Path.GetDirectoryName(fullDir) & Convert.ToString("\Schema.ini"))

答案 3 :(得分:-1)

使用模式文件帮助,这样就可以显式定义每个列类型,而不管内容