In this post let’s see how we can write data in a excel file into a database using a DataSet and SqlBulkCopy.
The concept here is fairly simple. First I am going to load data in the excel file into a DataSet and then for each tables in the DataSet, I am going to use SqlBulkCopy to push the data into the database. In my case, it will be a single table.
For demonstration purpose I have the following excel file, which has only one sheet which is named as “MySheet”.
Excel Sheet |
Now let’s see the whole process in action. I’m creating a new console application. I have the following method to get excel data into a table in DataSet.
public static DataSet ReadToDataSet(string filePath, string tableName)
{
DataSet ds = new DataSet();
OleDbCommand cmd = new OleDbCommand();
OleDbDataAdapter adapter = new OleDbDataAdapter();
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1;';");
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
// to select all the columns
//cmd.CommandText = "SELECT * FROM [MySheet$]";
// I am only selecting some columns
cmd.CommandText = "SELECT FirstName, LastName, Department FROM [MySheet$]";
adapter = new OleDbDataAdapter(cmd);
adapter.Fill(ds, tableName);
return ds;
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
return null;
}
Here when creating the OleDbConnection, in the query string along with the excel file path, I have mentioned some properties.
- "HDR=Yes;" indicates that the first row contains columnnames. If "HDR=No;", it indicates the opposite.
- MEX=1 is a safer way to retrieve data for mixed data columns. (You can read more on excel connection strings on http://www.connectionstrings.com/excel/).
Once I do that, now I have to push the data in my DataSet into the database. Before doing that here I have following two helper methods.
Following method will check if a table already exists with the given name in the database.
private static bool CheckWhetherTableExists(SqlConnection conn, string tableName)
{
bool isExist = false;
SqlCommand cmd;
try
{
conn.Open();
cmd = new SqlCommand("SELECT * FROM sysobjects where name = '" + tableName + "'", conn);
isExist = cmd.ExecuteScalar() == null ? false : true;
return isExist;
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
return true;
}
If the table doesn't exist, following method will create a table with all the column names as in provided DataTable. Please note, here for all columns I am using “varchar(MAX)” as the column type.
private static void CreateTableInDatabase(SqlConnection conn, DataTable dt)
{
bool isExist = false;
SqlCommand cmd;
try
{
conn.Open();
foreach (DataColumn dc in dt.Columns)
{
if (!isExist)
{
cmd = new SqlCommand("CREATE TABLE " + dt.TableName + " (" + dc.ColumnName + " varchar(MAX))", conn);
cmd.ExecuteNonQuery();
isExist = true;
}
else
{
cmd = new SqlCommand("ALTER TABLE " + dt.TableName + " ADD " + dc.ColumnName + " varchar(MAX)", conn);
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
Once I have the DataSet and the table created in database, all I have to do now is push the data in DataSet into the database.
public static void PushDataSetToDatabase(SqlConnection conn, DataSet ds)
{
try
{
foreach (DataTable dt in ds.Tables)
{
if (!CheckWhetherTableExists(conn, dt.TableName))
{
CreateTableInDatabase(conn, dt);
}
conn.Open();
using (SqlBulkCopy bulkcopy = new SqlBulkCopy(conn))
{
bulkcopy.DestinationTableName = dt.TableName;
bulkcopy.WriteToServer(dt);
}
}
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
static void Main(string[] args)
{
string filePath = @"D:\SampleExcelFile.xlsx";
DataSet ds = ReadToDataSet(filePath, "MyTable");
SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=MyTestDB;Integrated Security=True");
PushDataSetToDatabase(conn, ds);
}
Table in the Database |
So that's it. I have uploaded the sample into my SkyDrive.
Happy Coding.
Regards,
Jaliya
No comments:
Post a Comment