I want to track how many records are saved after uploading and importing an Excel file into my SQL database. Please can someone modify my code so that it can show the number of records stored in my table as well as a 'success' or 'failure' message?
Here is my code:
protected void btnSend_Click(object sender, EventArgs e) {
//file upload path
string path = fileuploadExcel.PostedFile.FileName;
//Create connection string to Excel work book
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Users\xxxxxx\Desktop\1-8-13-ct.xlsx';Extended Properties=Excel 12.0;Persist Security Info=False";
//Create Connection to Excel work book
OleDbConnection excelConnection =new OleDbConnection(excelConnectionString);
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select * from [Sheet1$]",excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "contact";
sqlBulk.WriteToServer(dReader);
excelConnection.Close();
}
You can use a DataTable instead of a DataReader so you can predetermine the number of rows that will be written. For example:
protected void btnSend_Click(object sender, EventArgs e)
{
//file upload path
string path = fileuploadExcel.PostedFile.FileName;
//Create connection string to Excel work book
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Users\xxxxxx\Desktop\1-8-13-ct.xlsx';Extended Properties=Excel 12.0;Persist Security Info=False";
//Create Connection to Excel work book
OleDbConnection excelConnection =new OleDbConnection(excelConnectionString);
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select * from [Sheet1$]",excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
// Datatable table = new DataTable();
DataTable table = new DataTable();
dReader = cmd.ExecuteReader();
table.Load(dReader);
SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "contact";
sqlBulk.WriteToServer(table);
excelConnection.Close();
int numberOfRowsInserted= table.Rows.Count;// <-- this is what was written.
string message=string.Format("<script>alert({0});</script>",numberOfRowsInserted);
ScriptManager.RegisterStartupScript(this, this.GetType(), "scr",message , false);
}
You could achieve this by creating a new command to read the number of rows from the sheet as so:
OleDbCommand cmd1 = new OleDbCommand("select count(*) from [Sheet1$]", excelConnection);
int rows = (int)cmd1.ExecuteScalar();
Or alternatively, do the same using the target database table.
The following hack (using reflection) is an option:
/// <summary>
/// Helper class to process the SqlBulkCopy class
/// </summary>
static class SqlBulkCopyHelper
{
static FieldInfo rowsCopiedField = null;
/// <summary>
/// Gets the rows copied from the specified SqlBulkCopy object
/// </summary>
/// <param name="bulkCopy">The bulk copy.</param>
/// <returns></returns>
public static int GetRowsCopied(SqlBulkCopy bulkCopy)
{
if (rowsCopiedField == null)
{
rowsCopiedField = typeof(SqlBulkCopy).GetField("_rowsCopied", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
}
return (int)rowsCopiedField.GetValue(bulkCopy);
}
}
And then use the class as follows:
int rowsCopied = SqlBulkCopyHelper.GetRowsCopied(bulkCopyObjectInYourCode);
Hope this helps.
from: https://stackoverflow.com/a/4474394/1727357
Related
am getting the following error while trying to import data from excel to the database.
The Microsoft Office Access database engine could not find the object
'C:\Users\DAKTARI\Desktop\smarttable.xls'
this is my code behind that am using.
public partial class Smarttable : System.Web.UI.Page
{
OleDbConnection Econ;
SqlConnection con;
string constr, Query, sqlconn;
protected void Page_Load(object sender, EventArgs e)
{
}
private void ExcelConn(string FilePath)
{
constr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\DAKTARI\Desktop\smarttable.xls;Extended Properties=""Excel 12.0 Xml;HDR=YES;""");
Econ = new OleDbConnection(constr);
}
private void connection()
{
sqlconn = ConfigurationManager.ConnectionStrings["SqlCom"].ConnectionString;
con = new SqlConnection(sqlconn);
}
private void InsertExcelRecords(string FilePath)
{
ExcelConn(FilePath);
Query = string.Format("Select [InvoiceNumber],[AmountPaid],[Remarks] FROM [C:\\Users\\DAKTARI\\Desktop\\smarttable.xls]", "Orders$");
OleDbCommand Ecom = new OleDbCommand(Query, Econ);
Econ.Open();
DataSet ds = new DataSet();
OleDbDataAdapter oda = new OleDbDataAdapter(Query, Econ);
Econ.Close();
oda.Fill(ds);
DataTable Exceldt = ds.Tables[0];
connection();
//creating object of SqlBulkCopy
SqlBulkCopy objbulk = new SqlBulkCopy(con);
//assigning Destination table name
objbulk.DestinationTableName = "smarttable";
//Mapping Table column
objbulk.ColumnMappings.Add("InvoiceNumber", "InvoiceNumber");
objbulk.ColumnMappings.Add("AmountPaid", "AmountPaid");
objbulk.ColumnMappings.Add("Remarks", "Remarks");
//inserting Datatable Records to DataBase
con.Open();
objbulk.WriteToServer(Exceldt);
con.Close();
}
protected void Button1_Click(object sender, EventArgs e)
{
string CurrentFilePath = Path.GetFullPath(FileUpload1.PostedFile.FileName);
InsertExcelRecords(CurrentFilePath);
}
}
Your Excel file format uses XLS which means for Office 2003 or earlier, but you're using ACE OLEDB provider which used for Office 2007 or later:
constr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\DAKTARI\Desktop\smarttable.xls;Extended Properties=""Excel 12.0 Xml;HDR=YES;"");
The correct usage is using Jet 4.0 provider like this:
constr = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=YES;'", FilePath);
Also you have second issue which a wrong query string is used to read the data inside worksheet:
Query = string.Format("Select [InvoiceNumber],[AmountPaid],[Remarks] FROM [C:\\Users\\DAKTARI\\Desktop\\smarttable.xls]", "Orders$");
This should be changed to proper form below:
Query = "SELECT [InvoiceNumber],[AmountPaid],[Remarks] FROM [Orders$]";
Change this line
Query = string.Format("Select [InvoiceNumber],[AmountPaid],[Remarks] FROM [C:\\Users\\DAKTARI\\Desktop\\smarttable.xls]", "Orders$");
To
Query = "Select [InvoiceNumber],[AmountPaid],[Remarks] FROM [Orders$]";
The FROM needs to be followed by the Sheet Name which is treated like a table
I tried import a Excel file using c#. When I tried to import a Excel file is creating a new Excel file with same name of importing file also that new file is corrupted. I don't why this happened.
My code:
private void button1_Click(object sender, EventArgs e)
{
//database name
string table = "importing";
// Excel sheet name
string excelQuery = "select * from [Sheet1$]";
try
{
//create connection strings
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\New folder (2)\\importing1.xls;Extended Properties=\"Excel 8.0;HDR=Yes;\";";
string sqlConnectionstring = "Data Source=LAB-2\\SQLEXPRESS;Initial Catalog=LMS;Persist Security Info=True;User ID=smart;Password=smart";
//To clear the previous data in the database
string resetQuery = "delete from " + table;
SqlConnection connection = new SqlConnection(sqlConnectionstring);
SqlCommand cmd = new SqlCommand(resetQuery, connection);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
//copy data from the excel file
OleDbConnection con = new OleDbConnection(connectionString);
OleDbCommand cmdOLEDB = new OleDbCommand(excelQuery, con);
con.Open();
OleDbDataReader dataReader = cmdOLEDB.ExecuteReader();
SqlBulkCopy bulkcopy = new SqlBulkCopy(sqlConnectionstring);
bulkcopy.DestinationTableName = table;
while (dataReader.Read())
{
bulkcopy.WriteToServer(dataReader);
}
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I have developed a functionality, where I import Excel sheet to the table. But when I upload the file and click on the button to import. The code doesn't works and gives me the below mentioned error. I tried with DataAdapter but that was also not working. Please see the error below:-
The Microsoft Office Access database engine could not find the object
'TableName'. Make sure the object exists and that you spell its
name and the path name correctly.
Also, Please see the code for your reference:-
private void ImporttoSQL(string sPath)
{
string sSourceConstr1 = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\AgentList.xls; Extended Properties=""Excel 8.0;HDR=YES;""", sPath);
string sSourceConstr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", sPath);
OleDbConnection sSourceConnection = new OleDbConnection(sSourceConstr);
using (sSourceConnection)
{
string sql = string.Format("Select [Merchant_Name],[Store_Name],[Store_Address],[City] FROM [MerchantTempDetail]", "Sheet1$");
OleDbCommand command = new OleDbCommand(sql, sSourceConnection);
sSourceConnection.Open();
conn.Open();
using (OleDbDataReader dr = command.ExecuteReader())
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.DestinationTableName = "MerchantTempDetail";
//You can mannualy set the column mapping by the following way.
// bulkCopy.ColumnMappings.Add("Mini_Category_Id", "Mini_Category_Id");
//bulkCopy.ColumnMappings.Add("CategoryId", "CategoryId");
bulkCopy.ColumnMappings.Add("Merchant_Name", "Merchant_Name");
bulkCopy.ColumnMappings.Add("Store_Name", "Store_Name");
bulkCopy.ColumnMappings.Add("Store_Address", "Store_Address");
bulkCopy.ColumnMappings.Add("City", "City");
bulkCopy.WriteToServer(dr);
}
}
}
}
Edited code :-
public static void ExcelToSqlServerBulkCopy()
{
// Connection String to Excel Workbook
// Jet4
string excelConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=AgentList.xls; Extended Properties=""Excel 8.0;HDR=YES;""";
// Ace Ole db 12
string excelAceOleDb12ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=AgentList.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelAceOleDb12ConnectionString))
{
OleDbCommand command = new OleDbCommand("Select [Merchant_Name],[Store_Name],[Store_Address],[City] FROM [Sheet1$]", connection);
// open excel
connection.Open();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = ConfigurationManager.ConnectionStrings["DefaultSQLConnectionString"].ConnectionString;
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "MerchantTempDetail";
bulkCopy.WriteToServer(dr);
}
}
}
}
protected void btnImport_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string sPath = Server.MapPath(FileUpload1.FileName);
FileUpload1.SaveAs(sPath);
ExcelToSqlServerBulkCopy();
}
}
You need to define 2 connections, one for the Excel source, another for the sql database you are bulk copying to. (This code has been tested) If you need to copy to an in-memory data table, use this example on MSDN.
public static void ExcelToSqlServerBulkCopy ()
{
// Connection String to Excel Workbook
// Jet4
string excelConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=AgentList.xls; Extended Properties=""Excel 8.0;HDR=YES;""";
// Ace Ole db 12
string excelAceOleDb12ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=AgentList.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelAceOleDb12ConnectionString))
{
OleDbCommand command = new OleDbCommand("Select [Merchant_Name],[Store_Name],[Store_Address],[City] FROM [AgentList$]", connection);
// open excel
connection.Open ();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader ())
{
// SQL Server Connection String
string sqlConnectionString = #"Data Source=.\SQLEXPRESS;Initial Catalog=StackOverflow;Integrated Security=True";
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy = new SqlBulkCopy (sqlConnectionString))
{
bulkCopy.DestinationTableName = "Q26382169";
bulkCopy.WriteToServer (dr);
}
}
}
}
Very important details using variable names above:
the database you are copying to (StackOverflow) must be created a priori.
the destination table (Q26382169) must exist in that database, DDL trivial, same columns as your Excel file.
Since you are using HDR=YES option, first row of Excel sheet must contain specified column names: Merchant_Name, Store_Name, Store_Address, City (without [])
The name of the sheet in the OleDbCommand (AgentList$)
Finally solved by debugging it.
private void ImporttoSQL(string sPath)
{
string sSourceConstr1 = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\AgentList.xls; Extended Properties=""Excel 8.0;HDR=YES;""", sPath);
string sSourceConstr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", sPath);
// string sSource = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + sPath + ";Extended Properties=Excel 8.0", sPath);
// string sDestConstr = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
OleDbConnection sSourceConnection = new OleDbConnection(sSourceConstr);
using (sSourceConnection)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultSQLConnectionString"].ConnectionString);
string sql = "Select [Merchant_Name],[Store_Name],[Store_Address],[City] FROM [Sheet1$]";
OleDbCommand command = new OleDbCommand(sql, sSourceConnection);
sSourceConnection.Open();
conn.Open();
using (OleDbDataReader dr = command.ExecuteReader())
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.DestinationTableName = "MerchantTempDetail";
bulkCopy.ColumnMappings.Add("Merchant_Name", "Merchant_Name");
bulkCopy.ColumnMappings.Add("Store_Name", "Store_Name");
bulkCopy.ColumnMappings.Add("Store_Address", "Store_Address");
bulkCopy.ColumnMappings.Add("City", "City");
bulkCopy.WriteToServer(dr);
}
}
}
}
I have excel file with 2 tables. I need to read this tables and get all the values from this tables. But all for what I have is:
OleDbConnection cnn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\MigrateExelSql\Include\TestDb.xlsx; Extended Properties=Excel 12.0;");
OleDbCommand oconn = new OleDbCommand("select * from [Sheet1$]", cnn);
cnn.Open();
OleDbDataAdapter adp = new OleDbDataAdapter(oconn);
DataTable dt = new DataTable();
adp.Fill(dt);
And I don't uderstand what I need to write for get the all values from Username and Email tables. Here is the .xlsx table TestDb Please can somebody help me, because I'm googling the second day and I have no idea for what I must to do.
And when I try to get values by this method it return me an error:
var fileName = string.Format("{0}\\Include\\TestDb.xlsx", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "Username");
var data = ds.Tables["Username"].AsEnumerable();
foreach (var item in data)
{
Console.WriteLine(item);
}
Console.ReadKey();
One more Edit:
string con =
#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\MigrateExelSql\Include\TestDb.xlsx; Extended Properties=Excel 12.0;";
using(OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbCommand command = new OleDbCommand("select * from [Sheet1$]", connection);
using(OleDbDataReader dr = command.ExecuteReader())
{
while(dr.Read())
{
var row1Col0 = dr[0];
Console.WriteLine(row1Col0);
}
}
}
Console.ReadKey();
This will read only first column, but when I try to read dr[1] it will return error: Index was outside bound of the array.
Your xlsx file contains only one sheet and in that sheet there is only one column.
A sheet is treated by the OleDb driver like a datatable and each column in a sheet is considered a datacolumn.
You can't read anything apart one table (Sheet1$) and one column (dr[0]).
If you try to read dr[1] then you are referencing the second column and that column doesn't exist in Sheet1.
Just to test, try to add some values in the second column of the Excel file.
Now you can reference dr[1].
I am importing excel data into sql server using SqlbulkCopy, but the problem is i want to prevent any duplicate records being entered. Is there a way by which duplicate can be ignored or deleted automatically?
protected void Button1_Click(object sender, EventArgs e)
{
string strFileType = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower();
string strFileName = FileUpload1.PostedFile.FileName.ToString();
FileUpload1.SaveAs(Server.MapPath("~/Import/" + strFileName + strFileType));
string strNewPath = Server.MapPath("~/Import/" + strFileName + strFileType);
string excelConnectionString = String.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strNewPath + "; Extended Properties=Excel 8.0;");
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
var command = new OleDbCommand("Select ID,Data FROM [Sheet1$]", connection);
connection.Open();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=ARBAAZ-1B14C081;Initial Catalog=abc;Integrated Security=True";
con.Open();
DataTable dt1 = new DataTable();
string s = "select count(*) from ExcelTable";
string r = "";
SqlCommand cmd1 = new SqlCommand(s, con);
try
{
SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
da1.Fill(dt1);
}
catch
{
}
int RecordCount;
RecordCount = Convert.ToInt32(cmd1.ExecuteScalar());
r = RecordCount.ToString();
Label1.Text = r;
con.Close();
int prv = Convert.ToInt32(r);
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "ExcelTable";
SqlBulkCopyColumnMapping mapping1 = new SqlBulkCopyColumnMapping("excelid", "id");
SqlBulkCopyColumnMapping mapping2 = new SqlBulkCopyColumnMapping("exceldata", "data");
bulkCopy.ColumnMappings.Add(mapping1);
bulkCopy.ColumnMappings.Add(mapping2);
bulkCopy.WriteToServer(dr);
}
con.Open();
DataTable dt = new DataTable();
s = "select count(*) from ExcelTable";
r = "";
SqlCommand cmd = new SqlCommand(s, con);
try
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
}
catch
{
}
RecordCount = Convert.ToInt32(cmd.ExecuteScalar());
r = RecordCount.ToString();
Label1.Text = r;
con.Close();
int ltr = Convert.ToInt32(r);
if (prv == ltr)
{
Label1.Text = "No records Added";
}
else
{
Label1.Text = "Records Added Successfully !";
}
}
}
}
Can this problem be fixed by creating a trigger to delete duplicates? if yes how? i am a newbie i have never created a trigger.
Another problem is no matter what i try i am unable to get column mapping to work. I am unable to upload data when column names in excel sheet and database are different.
You can create INDEX
CREATE UNIQUE INDEX MyIndex ON ExcelTable(id, data) WITH IGNORE_DUP_KEY
And when you will insert data with bulk to db, all duplicate values will not inserted.
no, either you manage it on your dr object on you code before you load it into the db (like running a DISTINCT operation) or you create a trigger on the DB to check. The trigger will reduce the bulk insert's performace though.
Another option would be to bulk insert into a temp table and then insert into your destination table FROM your temp table using a select DISTINCT
as far as I remember,
you could filter out the redundant rows when importing from the excel file itself.
the following SQL query should be used in the OleDbCommand constructor.
var command = new OleDbCommand("Select DISTINCT ID,Data FROM [Sheet1$]", connection);