Okay this may get long, but this is what I'm doing.
I'm using ASP.NET 2.0
The concept: I need to import a CSV files to an SQL server. However the
csv files come to us with different headers and some extra fields in
some cases.
So I created an ASP.NET page that allows the customer to select the csv
file to be imported.
Once the file is uploaded they can preview the first 5 records to check
the data.
Then they click import headers. The CSV file headers are loaded into a
list box on the left and the SQL headers are loaded into a listbox on
the right.
They now can select the csv header and then the sql header and click
connect. The two selected values are put in two more list boxes that
represent the connection (mappings)
Once they have selected the desired mappings they can click upload
which calls bulk copy to send the csv data to the sql server.
This is where the problem and questions are:
First, I can get it to work fine if the csv file is laid out just like
the SQL server.
But when the CSV file has an extra field and is not mapped it will
crash.
Some csv files come with extra data that we do not want uploaded so we
don't include them in our mapping. Exampl : ADD1 ADD2 ADD3 our
SQL server only as ADD1 ADD2. So when I make the connections I skip
ADD3 in the mappings and go on the next mappings.
Everything works and uploads to the SQL server if the headers are in
order and none are skipped.
Can CSVreader handle this type of mapping? Or does it require all
headers to be mapped? Do they have to be in order? IE header 1 from the
csv mapped to header 5 of the csv? Here is the code I'm using...
Protected Sub uploadButton_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles uploadButton.Click
txtDate.Text = DateTime.Now.ToString
Dim FileLocation As String = txtFilePath.Text
If txtJobNumber.Text = "" Then
Exit Sub
End If
Using loader As CsvDataReader = New CsvDataReader(FileLocation)
loader.HasHeaders = True
For intLoopIndex As Integer = 0 To ListMapCSV.Items.Count -
1
loader.Columns.Add("nvarchar")
Next
loader.Columns.Add("int", "JobNumber")
loader.Columns.Add("nvarchar", "Uploaded")
AddHandler loader.ReadRecord, AddressOf AddJobNumber
AddHandler loader.ReadRecord, AddressOf AddUploaded
Using bulkCopy As Data.SqlClient.SqlBulkCopy = New
Data.SqlClient.SqlBulkCopy("Data
Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated
Security=True;User Instance=True")
bulkCopy.DestinationTableName = "tblRecall"
'"Data Source=cyan;Initial Catalog=vw01;User
ID=sa;Password=3Terra-"
For intLoopIndex As Integer = 0 To
ListMapCSV.Items.Count - 1
bulkCopy.ColumnMappings.Add(ListMapCSV.Items(intLoopIndex).ToString,
ListMapSQL.Items(intLoopIndex).ToString) ' map First to first_name
Next
bulkCopy.ColumnMappings.Add("JobNumber", "JobNumber") '
map UserID from Session to user_id
bulkCopy.ColumnMappings.Add("Uploaded",
"DateTimeUploaded") ' map UserID from Session to user_id
bulkCopy.WriteToServer(loader)
End Using
End Using
ListMapCSV.Items.Clear()
ListMapSQL.Items.Clear()
ListCSV.Items.Clear()
End Sub
Original:
For intLoopIndex As Integer = 0 To ListMapCSV.Items.Count - 1
loader.Columns.Add("nvarchar")
Next
Fixed:
For intLoopIndex As Integer = 0 To ListCSV.Items.Count - 1
loader.Columns.Add("nvarchar")
Next
When I changed this, it seemed to load successfully. I haven't verified
the data in the database yet, and I need to look at something that
seemed odd about how the column names were arranged with how you had
it, but this fix makes perfect sense and I think it will resolve all
your issues.
Bruce Dunwiddie
I used your updated csv.dll and poof it all worked as you said it work
on your end.
Thank you very much...
:-) Now the fun part of user testing of the entire web application.
PS. To everyone looking for a solution working with CSV files, this is
by far the best.... Our company tried several others but none of them
had come close to the versatility, speed, and awesome customer service
as CsvReader.