How to specify the delimiter when importing CSV files via OLEDB in C#
I need to perform a complex import in a Microsoft SQL Server 2000.
Since doing it in a DTS is too complicated, I'm trying to do it with a little C# program, but I'm having problems when I need to import a CSV files: this file is using semicolons as field delimiters instead of commas and I can't get the .NET's OLE DB provider to recognize it.
I already found various "solutions" on the net like using Extended Properties="Text; Format=Delimited"
or ``Extended Properties="Text; Format=Delimited(;)"in the connection string or using a
schema.ini` file to no avail.
This is the actual code I'm using:
DataTable Table = new DataTable();
using (OleDbConnection Connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=\"Text;HDR=Yes;Format=Delimited\""))
{
Connection.Open();
using (OleDbCommand Command = Connection.CreateCommand())
{
Command.CommandText = "select [Field 1], [Field 2] from [file.csv]";
using (OleDbDataAdapter Adapter = new OleDbDataAdapter(Command))
{
Adapter.Fill(Table);
}
}
}
using (SqlConnection Connection = new SqlConnection("Data Source=server; Initial Catalog=database; User Id=user; Password=password;"))
{
Connection.Open();
using (SqlCommand Command = Connection.CreateCommand())
{
Command.CommandText = "insert into [table] ([field_1], [field_2], ...) values (@field_1, @field_2, ...)";
Command.Parameters.Add("field_1", SqlDbType.Date, 0, "Field 1");
Command.Parameters.Add("field_2", SqlDbType.VarChar, 100, "Field 2");
...
using (SqlDataAdapter Adapter = new SqlDataAdapter())
{
Adapter.InsertCommand = Command;
Adapter.Update(Table);
}
}
}
Any ideas on how to achieve using the semicolon as the field separator without relying on external libriaries?
Notes:
- The "without relying on external libriaries" bit is because I need to import the file directly into the database and no library I found can do this (they return strings), and our PHB won't drop even a penny for a commercial solution.
- I know I can import the file via a DTS, but I need to perform complex branching on the workflow and file alterations before and after th开发者_如何学编程e import, and that would result in jumping in and out of the DTS.
- Doing everything inside the DTS would not be practical for me, as I'm not that skilled in ActiveX and VBScript coding.
Thanks in advance, Andrea.
Edit 1 - @andyb:
Test program code for schema.ini
approach:
String ConnectionString = String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=\"Text\"", Environment.CurrentDirectory);
DataTable Table = new DataTable();
using (OleDbConnection Connection = new OleDbConnection(ConnectionString))
{
Connection.Open();
using (OleDbCommand Command = Connection.CreateCommand())
{
Command.CommandText = "select * from [file.csv]";
using (OleDbDataAdapter Adapter = new OleDbDataAdapter(Command))
{
Adapter.Fill(Table);
}
}
}
Commenter is right that you have your provider syntax the wrong way round.
However, this isn't the problem. Unfortunately, you cannot specify a custom delimiter in your oledb connection string. Instead, create a schema.ini file in the same directory as your source file containing the following:
[file.csv]
Format=Delimited(;)
Clumsy, but it does work.
The schema.ini file has to be saved in Unicode or ANSI, not as UTF-8.
Your data file must also be saved as Unicode not UTF-8.
You have to write your csv file name inside the schema.ini file (not [file.csv], e.g.: test.csv will have a schema.ini with [test.csv] text at line 0:
[test.csv]
Format=Delimited(;)
精彩评论