While inserting the data from excel to database it throwing the above error
Here is my code:
void insertDB()
{
string FileName = lblFileName.Text;
string Extension = Path.GetExtension(FileName);
string FolderPath = Server.MapPath(ConfigurationManager.AppSettings["FolderPath"]);
string conStr = "";
switch (Extension)
{
case ".xls": //Excel 97-03
conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FolderPath + FileName + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
break;
case ".xlsx": //Excel 07
conStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FolderPath + FileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\"";
break;
}
try
{
using (var context = new LQTransAgentSeaFreightRateDataContext())
{
string sql = string.Format("Select * FROM [{0}]" , ddlSheets.SelectedValue);
using (var myConnection = new OleDbConnection(conStr))
using (var myCommand = new OleDbCommand(sql, myConnection))
{
myConnection.Open();
var myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
context.TB_TransAgentSeaFreightRates.InsertOnSubmit(new TB_TransAgentSeaFreightRate()
{
tASF_VCPOD = myReader.GetString(0),
tASF_VCPOL = myReader.GetString(1),
tASF_VCForwarder = myReader.GetString(2),
tASF_VCForwarderReference = myReader.GetString(3),
tASF_VCShippingLine = myReader.GetString(4),
tASF_VCContainerType = myReader.GetString(5),
tASF_VCContainerSize = myReader.GetString(6),
tASF_DTEValidFrom = Convert.ToDateTime(myReader.GetString(7)),
tASF_DTEValidTo = Convert.ToDateTime(myReader.GetString(8)),
tASF_NUBasicRate = mobjGenlib.ConvertLong(myReader.GetString(9)),
tASF_NUPAF = mobjGenlib.ConvertLong(myReader.GetString(10)),
tASF_NUCAF = mobjGenlib.ConvertLong(myReader.GetString(11)),
tASF_NUPSS = mobjGenlib.ConvertLong(myReader.GetString(12)),
tASF_NUTotalAmount = mobjGenlib.ConvertLong(myReader.GetString(13)),
tASF_NUFreeDays = mobjGenlib.ConvertLong(myReader.GetString(14)),
tASF_VCCreditDays = myReader.GetString(15),
tASF_VCNITDeposit = myReader.GetString(16),
tASF_NUIsActive = 1,
tASF_mCMP_NUUniqueId = mobjGenlib.ConvertLong(TXTCompanyID.Text)
});
}
}
context.SubmitChanges();
}
}
catch (Exception ex)
{
lblMessage.ForeColor = System.Drawing.Color.White;
lblMessage.Text = ex.Message;
}
}
I don't have an idea to how to make it to work fine...if any one suggest me it would be very helpful.
Thanks in adavance.
The error was caused by improper unboxing. (Ref:
http://msdn.microsoft.com/en-us/library/b95fkada(v=vs.80).aspx)
Response Limitations: I don't know the property types for
TB_TransAgentSeaFreightRate.
Assumption: The types of the data being assigned to the properties matches the types of
the properties.
There are 2 ways, that I see, of handling this from a debugging
standpoint
Given the way your are doing this, you won't be able to see the exact
failure. You could temporarily move the initialization of the
members out of the new statement.
Alternatively, you could debug through the code repetitively each
time commenting out 1 line from the assignments until you have found
the offending line.
I am discounting Convert.ToDateTime as the source of the problem. It throws a
FormatException for and invalid DateTime.
Ref. http://msdn.microsoft.com/en-us/library/xhz1w05e(v=vs.110).aspx
My guess is that it is occurring on one of the mobjGenlib.ConvertLong. You're going to
have to debug through the code to find the line in question. Also keep in mind that this error is happening because of the data. You will need to account for this type of error, and deal with it in the code.
Related
I have an upload button that can upload excel file and save it to my database. What I want to happen is that if there's one or more data in that excel file that already existing the other data will also not be uploaded though it's not yet existing. My code for adding it to the database and upload button are below.
Add to database
private void AddNewTrainee(string strdelname, string strrank, string strcomp, string strcourse, string strcenter, string strinst,
string strsdate, string stredate, string strcissued, string strcnumber, string strremark, int recdeleted, string credate, string update, int fromupload)
{
connection.Open();
String checkDateAndName = "Select count(*) from Trainees where StartDate= '" + strsdate + "' and Delegate='" + strdelname + "' and REC_DELETED = 0 ";
SqlCommand cmd = new SqlCommand(checkDateAndName, connection);
int dataRepeated = Convert.ToInt32(cmd.ExecuteScalar().ToString());
bool boolDataRepated;
connection.Close();
if (!(dataRepeated >= 1))
{
boolDataRepated = false;
}
else
boolDataRepated = true;
connection.Open();
string certNumber = "Select * from CertID_Table update CertID_Table set CertificateID = CertificateID + 1 from CertID_Table ";
SqlCommand cmdCert = new SqlCommand(certNumber, connection);
using (SqlDataReader oReader = cmdCert.ExecuteReader())
{
while (oReader.Read())
{
string test1 = oReader["CertificateID"].ToString();
ViewState["certnumber"] = test1;
}
}
connection.Close();
strcnumber = (string)ViewState["certnumber"];
if (boolDataRepated == false)
{
string path = "D:\\Intern\\BASSWeb\\SQLCommands\\AddSQL.txt";
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
sb.Append(sr.ReadLine());
}
string sql = sb.ToString();
try
{
connection.Open();
SqlCommand cmd1 = new SqlCommand(sql, connection);
cmd1.Parameters.AddWithValue("#delName", strdelname);
cmd1.Parameters.AddWithValue("#rank", strrank);
cmd1.Parameters.AddWithValue("#comp", strcomp);
cmd1.Parameters.AddWithValue("#course", strcourse);
cmd1.Parameters.AddWithValue("#center", strcenter);
cmd1.Parameters.AddWithValue("#instructor", strinst);
cmd1.Parameters.AddWithValue("#sdate", strsdate);
cmd1.Parameters.AddWithValue("#edate", stredate);
cmd1.Parameters.AddWithValue("#cissued", strcissued);
cmd1.Parameters.AddWithValue("#cnumber", strcnumber);
cmd1.Parameters.AddWithValue("#remark", strremark);
cmd1.Parameters.AddWithValue("#rdeleted", recdeleted);
cmd1.Parameters.AddWithValue("#cdate", credate);
cmd1.Parameters.AddWithValue("#udate", update);
cmd1.Parameters.AddWithValue("#fupload", fromupload);
cmd1.CommandType = CommandType.Text;
cmd1.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert/Update Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
connection.Close();
}
}
}
else
{
string script = "alert(\"The data already exists\");";
ScriptManager.RegisterStartupScript(this, GetType(), "ServerControlScript", script, true);
}
}
Upload Button
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
try
{
string path = Path.GetFileName(FileUpload1.FileName);
path = path.Replace(" ", "");
FileUpload1.SaveAs(Server.MapPath("~/Datas/") + path);
String ExcelPath = Server.MapPath("~/Datas/") + path;
OleDbConnection mycon = new OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0; Data Source = " + ExcelPath + "; Extended Properties=Excel 8.0; Persist Security Info = False");
mycon.Open();
OleDbCommand cmdX = new OleDbCommand("select * from [Sheet1$]", mycon);
OleDbDataReader dr = cmdX.ExecuteReader();
while (dr.Read())
{
delegateName = dr[0].ToString();
rankPos = dr[1].ToString();
company = dr[2].ToString();
courseTitle = dr[3].ToString();
trainingCenter = dr[4].ToString();
instructor = dr[5].ToString();
staDa = DateTime.Parse(dr[6].ToString());
string startDate = staDa.ToString("MM/dd/yyyy");
endDa = DateTime.Parse(dr[7].ToString());
string endDate = endDa.ToString("MM/dd/yyyy");
certIssued = dr[8].ToString();
certNum = dr[9].ToString();
remarks = dr[10].ToString();
recDeleted = 0;
dateCreated = DateTime.Now.ToString("MM/dd/yyyy HH:mm");
dateUpdated = string.Empty;
fromUpload = 1;
AddNewTrainee(delegateName, rankPos, company, courseTitle, trainingCenter, instructor,
startDate, endDate, certIssued, certNum, remarks, recDeleted, dateCreated, dateUpdated, fromUpload);
}
}
catch (Exception ex)
{
string errorMessage = "alert(\"ERROR: " + ex.Message.ToString() + " \");";
ScriptManager.RegisterStartupScript(this, GetType(), "ServerControlScript", errorMessage, true);
}
}
else
{
string errorMessage = "alert(\"ERROR: You have not specified a file \");";
ScriptManager.RegisterStartupScript(this, GetType(), "ServerControlScript", errorMessage, true);
}
PopulateData();
}
You have to set the transferMode to 'Streamed', otherwise you will always get one file.
Have a look at this article: https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-enable-streaming
I think there is a few things you'll need to tackle to reach your end goal.
Use a multiselect method and a get a post list of all files required
for upload.
Do your processing requirements in a Transaction
When your done processing, commit or rollback the transaction as necessary and keep the data you want.
Study the link I posted a little bit. At first transaction seem a little bit overwhelming, but they are actually very simple. Maybe I can help you get started in your understandings. There are really only three extra steps;
1.
Initialize a transaction object after you create a command.
SqlTransaction transaction = connection.BeginTransaction();
2.
On all of your Sql Commands (Inserts,updates, deletes ect) attach the transaction.
cmd.Transaction = transaction;
This will allow you to Execute the SqlCommands without actually putting them into your database. Lastly, when you've processed all of your inserts and updates you can do the final step. The using statement is not required, just good practice. That could be the next thing you'll want to understand it is very helpful.
3.
Commit all SqlCommands to the database.
transaction.Commit();
If at any point during your data processing, something goes wrong than you can rollback every transaction like this.
transaction.Rollback();
While uploading Excel there are values in columns in alphabets, so taking into datatable the values are getting blank.
below is the code which is making it blank.
string filename = Path.GetFileName(fluploadData.FileName);
// FileUpload.SaveAs(Server.MapPath("~/") + filename);
string filenamewithoutrext = string.Empty;
FileExt = Path.GetExtension(fluploadData.FileName).ToLower();
if (Path.GetExtension(fluploadData.FileName).ToLower() != ".xls" &&
Path.GetExtension(fluploadData.FileName).ToLower() != ".xlsx"
)
{
Response.Write("Only .xls,.xlsx are allowed.!");
return;
}
filenamewithoutrext = Path.GetFileNameWithoutExtension(fluploadData.FileName).ToLower();
string path = Server.MapPath("UploadData\\");
string filename_ = filenamewithoutrext;
// DeleteDirectory(path);
if (!Directory.Exists(path)) // CHECK IF THE FOLDER EXISTS. IF NOT, CREATE A NEW FOLDER.
{
Directory.CreateDirectory(path);
}
else
{
foreach (string file in Directory.GetFiles(path))
{
File.Delete(file);
}
}
string fname;
fname = path + filename_ + ".xls";
fluploadData.SaveAs(fname);
HttpContext.Current.Session["ExcelFilePath"] = fname;
string conStr = "";
System.Data.DataTable dtExcelRows = new System.Data.DataTable();
switch (FileExt)
{
case ".xls": //Excel 97-03
conStr = System.Configuration.ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
break;
case ".xlsx": //Excel 07
conStr = System.Configuration.ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
break;
}
conStr = String.Format(conStr, fname, "YES");
System.Data.OleDb.OleDbConnection connExcel = new System.Data.OleDb.OleDbConnection(conStr);
System.Data.OleDb.OleDbCommand cmdExcel = new System.Data.OleDb.OleDbCommand();
System.Data.OleDb.OleDbDataAdapter oda = new System.Data.OleDb.OleDbDataAdapter();
cmdExcel.Connection = connExcel;
connExcel.Open();
System.Data.DataTable dtExcelSchema = connExcel.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
System.Data.DataTable dtExcelColumnsTable = connExcel.GetSchema("Columns");
//string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString().Replace('\'', ' ').Trim();
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString().Trim();
cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
oda.SelectCommand = cmdExcel;
oda.Fill(dtExcelRows);
connExcel.Close();
The problem is likely caused by mixed datatypes in a column. For example the first few rows have a number value so it is then presumed to be a column with a numeric type. When a non numeric value is encountered it can't be parsed and is ignored.
See this answer for some ways around this. They may include setting a value of IMEX=1 in the connection string or treating the header row as data (HDR=0) - assuming your column names are non numeric.
You might also want to look into specific libraries which are designed for reading/writing Excel Documents, I have had good experiences with EPPlus but it only works for .xlsx files not .xls, NPOI which I haven't used can do both.
As others have mentioned if you are just using the Excel document as a datasource for the applications it may be better to look into an alternative solution such as SQL. If you have a requirement to process spreadsheets from third parties obviously that would not be an option.
I am facing a problem while uploading an excel sheet using oledb. Couple of weeks ago, it was working perfectly so I moved to different module.
But when I am testing and debugging the application now it is throwing an error.
Someone please look into this as I am not able to resolve this issue, also, their is no resolution posted when I searched on google as well....
Error: DisconnectedContext was Detected
Transition into COM context 0x673dd0 for this RuntimeCallableWrapper failed with
the following error: The object invoked has disconnected from its clients.
(Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED)). This is typically
because the COM context 0x673dd0 where this RuntimeCallableWrapper was
created has been disconnected or it is busy doing something else. Releasing
the interfaces from the current COM context (COM context 0x673d18). This
may cause corruption or data loss. To avoid this problem, please ensure
that all COM contexts/apartments/threads stay alive and are available for
context transition, until the application is completely done with the
RuntimeCallableWrappers that represents COM components that live inside them.
My Code: For FileUpload
string filefullpath = null;
try
{
string filepath = Server.MapPath("~/BulkUploadFile/");
string filename = fuDatabaseFile.FileName;
string filetype = Path.GetExtension(filename);
string filenamewithoutextension = Path.GetFileNameWithoutExtension(filepath);
string append = DateTime.Now.ToString("yyyyMMddHHmmssfffFFF");
string newfilename = filenamewithoutextension + append + filetype;
filefullpath = filepath + newfilename;
fuDatabaseFile.SaveAs(filefullpath);
}
catch (Exception ex)
{
}
Code for ExcelConnectivity:
FileUpload();
string excelconnectionstring = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + FileUpload() + ";Extended Properties=Excel 12.0;Persist Security Info=False";
using (OleDbConnection excelcon = new OleDbConnection(excelconnectionstring))
{
using (OleDbCommand command = new OleDbCommand("", excelcon))
{
command.CommandText = "Select * from [Sheet1$]";
excelcon.Open();
using (OleDbDataReader reader = command.ExecuteReader())
{
DataTable table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("EmpID");
}
}
}
I need to specify the file path of an access db as a command line argument and pass it to my C# program, which will open and perform operation on it.
In the Command Prompt I type F:\\count which I should able to access using args[0], but I get Invalid value for key 'data source' exception.
When I put the same path in the code as string path = "F:\\count" then it works.
Please tell me what I'm doing wrong! I'm lost.
Here is my code:
namespace CountProjectPages
{
public class CountProjectPages
{
private static OleDbConnection myConnection;
static void Main(string[] args)
{
try
{
string path = args[0];
AppDomain.CurrentDomain.SetData("DataDirectory",path);
myConnection = new OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;Data Source=|DataDirectory|\\test.mdb;Jet OLEDB:Database Password=aaa");
string myScalarQuery = "SELECT COUNT (Content.Page) from Content";
OleDbCommand myCommand = new OleDbCommand(myScalarQuery, myConnection);
myConnection.Open();
int total = (Int32)myCommand.ExecuteScalar();
Console.WriteLine(total);
Console.WriteLine("DataSource: {0}",myConnection.DataSource);
}
catch (Exception ex)
{
Console.WriteLine("Ex: " + ex);
}
finally
{
myConnection.Close();
}
}
}
}
In response to your question
do you think that it's possible to pass the file name (e.g. test.mdb) as a command line argument too?
How to use command-line switches in Microsoft Access
Check this code:
static void Main(string[] args)
{
string dbPath = null;
if (args.Length > 0)
{
dbPath = args[0];
string connectionString = "PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=" + dbPath + ";";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
//TODO: handle other db commands...
}
}
}
Make sure that command argument is passed as complete or relative path to mdb file using quotes like this: "f:\some directory\MyDataBase.mdb"
I've been working on a program to read a dbf file, mess around with the data, and save it back to dbf. The problem that I am having is specifically to do with the writing portion.
private const string constring = "Driver={Microsoft dBASE Driver (*.dbf)};"
+ "SourceType=DBF;"
+ "DriverID=277;"
+ "Data Source=¿;"
+ "Extended Properties=dBASE IV;";
private const string qrystring = "SELECT * FROM [¿]";
public static DataTable loadDBF(string location)
{
string filename = ConvertLongPathToShort(Path.GetFileName(location));
DataTable table = new DataTable();
using(OdbcConnection conn = new OdbcConnection(RTN(constring, filename)))
{
conn.Open();
table.Load(new OdbcCommand(RTN(qrystring, filename), conn).ExecuteReader());
conn.Close();
}
return table;
}
private static string RTN(string stmt, string tablename)
{ return stmt.Replace("¿", tablename); }
[DllImport("Kernel32", CharSet = CharSet.Auto)]
static extern Int32 GetShortPathName(
String path, // input string
StringBuilder shortPath, // output string
Int32 shortPathLength); // StringBuilder.Capacity
public static string ConvertLongPathToShort(string longPathName)
{
StringBuilder shortNameBuffer;
int size;
shortNameBuffer = new StringBuilder();
size = GetShortPathName(longPathName, shortNameBuffer, shortNameBuffer.Capacity);
if (size >= shortNameBuffer.Capacity)
{
shortNameBuffer.Capacity = size + 1;
GetShortPathName(longPathName, shortNameBuffer, shortNameBuffer.Capacity);
}
return shortNameBuffer.ToString();
}
This is what I'm working with. I've tried a number of methods to write a new file, none of them productive. To be honest, while normally I would be an advocate of form and function, I just want the damn thing to work, this app is supposed to do one very specific thing, it's not going to simulate weather.
-=# Edit #=-
I've since discontinued the app due to time pressure, but before I scrapped it I realised that the particular format of dbf I was working with had no primary key information. This of course meant that I had to essentially read the data out to DataTable, mess with it, then wipe all the records in the dbf and insert everything from scratch.
Screw that for a lark.
For people coming here in the future: I wrote this today and it works well. The filename is without the extension (.dbf). The path (used for connection) is the directory path only (no file). You can add your datatable to a dataset and pass it in. Also, some of my datatypes are foxpro data types and may not be compatible with all DBF files. Hope this helps.
public static void DataSetIntoDBF(string fileName, DataSet dataSet)
{
ArrayList list = new ArrayList();
if (File.Exists(Path + fileName + ".dbf"))
{
File.Delete(Path + fileName + ".dbf");
}
string createSql = "create table " + fileName + " (";
foreach (DataColumn dc in dataSet.Tables[0].Columns)
{
string fieldName = dc.ColumnName;
string type = dc.DataType.ToString();
switch (type)
{
case "System.String":
type = "varchar(100)";
break;
case "System.Boolean":
type = "varchar(10)";
break;
case "System.Int32":
type = "int";
break;
case "System.Double":
type = "Double";
break;
case "System.DateTime":
type = "TimeStamp";
break;
}
createSql = createSql + "[" + fieldName + "]" + " " + type + ",";
list.Add(fieldName);
}
createSql = createSql.Substring(0, createSql.Length - 1) + ")";
OleDbConnection con = new OleDbConnection(GetConnection(Path));
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = createSql;
cmd.ExecuteNonQuery();
foreach (DataRow row in dataSet.Tables[0].Rows)
{
string insertSql = "insert into " + fileName + " values(";
for (int i = 0; i < list.Count; i++)
{
insertSql = insertSql + "'" + ReplaceEscape(row[list[i].ToString()].ToString()) + "',";
}
insertSql = insertSql.Substring(0, insertSql.Length - 1) + ")";
cmd.CommandText = insertSql;
cmd.ExecuteNonQuery();
}
con.Close();
}
private static string GetConnection(string path)
{
return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=dBASE IV;";
}
public static string ReplaceEscape(string str)
{
str = str.Replace("'", "''");
return str;
}
What kind of dbf file are you working with? (There are several, e.g. dBase, FoxPro etc that are not 100% compatible.) I have gotten this to work with the Microsoft Visual FoxPro OleDB Provider from C#, you might give that a shot instead of using the dBase ODBC driver.
Using ADO.Net to read and write dbf files turns out to be really slow so I would suggest you use an alternative approach.
One option would be to use the old DAO 3.6 library. This is much faster and just as compatible, but depends on a com object to work.
A better approach would be to use the open source DBFExporter component. It may require some code to set up (you need a class with properties that describe your recordset and the properties must have certain attributes set) but after that it works really well. It is fast to use but it doesn't read dbf files. The component is licences under the LGPL so you should be able to use it in commercial code.