I am trying to upload some data from csv file to sql server using SqlBulkCopy
The problem here is that the values get changed automatically
eg 0.9824 becomes 0.982400000095367
Here is the code that I am using
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(strConnectionString, SqlBulkCopyOptions.FireTriggers))
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("dt", typeof(DateTime)));
dt.Columns.Add(new DataColumn("wreb", typeof(string)));
dt.Columns.Add(new DataColumn("zid", typeof(int)));
dt.Columns.Add(new DataColumn("zone_name", typeof(string)));
dt.Columns.Add(new DataColumn("region", typeof(string)));
dt.Columns.Add(new DataColumn("iloss", typeof(float)));
dt.Columns.Add(new DataColumn("dloss", typeof(float)));
for (int i = 0; i < DataDS.Tables[0].Rows.Count; i++)
{
DataRow myDr = dt.NewRow();
myDr["dt"] = DateTime.ParseExact(DataDS.Tables[0].Rows[i]["dt"].ToString(), "d/M/yyyy", null);
myDr["wreb"] = DataDS.Tables[0].Rows[i]["wreb"].ToString();
myDr["zid"] = DataDS.Tables[0].Rows[i]["zid"].ToString();
myDr["zone_name"] = DataDS.Tables[0].Rows[i]["zone_name"].ToString();
myDr["region"] = DataDS.Tables[0].Rows[i]["region"].ToString();
myDr["iloss"] = DataDS.Tables[0].Rows[i]["iloss"].ToString();
myDr["dloss"] = DataDS.Tables[0].Rows[i]["dloss"].ToString();
dt.Rows.Add(myDr);
myDr = null;
}
bulkCopy.BulkCopyTimeout = 0;
bulkCopy.ColumnMappings.Add("dt", "Zdate");
bulkCopy.ColumnMappings.Add("wreb", "Entity");
bulkCopy.ColumnMappings.Add("zid", "ZoneID");
bulkCopy.ColumnMappings.Add("zone_name", "Zone_Name");
bulkCopy.ColumnMappings.Add("region", "region");
bulkCopy.ColumnMappings.Add("iloss", "iloss");
bulkCopy.ColumnMappings.Add("dloss", "dloss");
bulkCopy.DestinationTableName = "tbl_zloss";
bulkCopy.WriteToServer(dt);
}
Looks like you're using float which is an imprecise datatype.
Use decimal to get exact values. Precision and scale depend on your data
Related
my DataRow object is emtpy no matter how I try to initialize it. Here is the source code:
private DataTable ReadFileIntoDb(MemoryStream file)
{
file.Position = 0;
var sr = new StreamReader(file,Encoding.GetEncoding(1251),true);
var dt = new DataTable();
Console.WriteLine("datatable success");
dt.Columns.Add(new DataColumn("description", typeof(String)));
dt.Columns.Add(new DataColumn("code", typeof(String)));
dt.Columns.Add(new DataColumn("cardnumber", typeof(String)));
dt.Columns.Add(new DataColumn("costcentrecode", typeof(int)));
dt.Columns.Add(new DataColumn("costcentre", typeof(String)));
dt.Columns.Add(new DataColumn("article_description", typeof(String)));
dt.Columns.Add(new DataColumn("trans_date", typeof(DateTime)));
dt.Columns.Add(new DataColumn("article_price", typeof(Double)));
dt.Columns.Add(new DataColumn("article_quantity", typeof(Double)));
dt.Columns.Add(new DataColumn("netto", typeof(Double)));
dt.Columns.Add(new DataColumn("brutto", typeof(Double)));
dt.Columns.Add(new DataColumn("mwst", typeof(Double)));
dt.Columns.Add(new DataColumn("beleg", typeof(Double)));
dt.Columns.Add(new DataColumn("oberverkaufsgruppe", typeof(int)));
dt.Columns.Add(new DataColumn("house", typeof(String)));
dt.Columns.Add(new DataColumn("id", typeof(String)));
//1. row gets skipped
string line = sr.ReadLine();
Console.WriteLine("line contains:" + line);
line = sr.ReadLine();
do
{
string[] itemArray = line.Split(';');
DataRow row = dt.NewRow();
row.ItemArray = itemArray; //doesnt work and throws ArgumentException
itemArray.CopyTo(row.ItemArray, 0); //doesnt work either
for (int i = 0; i < 14; i++) //also doesnt work and leaves it empty
{
row.ItemArray[i] = itemArray[i];
Console.WriteLine(row.ItemArray[i]);
}
row["id"] = Guid.NewGuid().ToString();
row["house"] = "";
dt.Rows.Add(row);
line = sr.ReadLine();
} while (!string.IsNullOrEmpty(line));
ReadFileIntoDb gets the content of a csv file as a parameter. Right now i reduced the csv content to only two lines which of one is just the header. The content looks like this and gets parsed successfully into var sr:
Bewohner;1102284;1102284;42600;ASG ROT;Menü (Inklusivleistung);01.07.2022;0;1;;;;;2000003
As you can see this file contains 14 elements, some of which are empty. My DataTable also contains 14 columns and 2 additional which I set inside the code however and their values do not come from the csv.
After performing the database operations my tables remain empty because I believe that row.ItemArray always remains empty so nothing gets added to the database. But I don't understand why it stays empty and why i get a ArgumentException. The source array itemArray is NOT empty and is also of length 14. So why does the exception get thrown if row.ItemArray is bigger in length? It has 16.
Look into this ,I change the input string a bit
The line i added is
for (int i = 0; i < itemArray.Length; i++)
{
if (string.IsNullOrWhiteSpace(itemArray[i]))
{
itemArray[i] = null;
}
}
for replacing the empty values as null in the given input , without this i got the error
Unhandled exception. System.ArgumentException: Input string was not in a correct format.Couldn't store <> in netto Column. Expected type is Double.
---> System.FormatException: Input string was not in a correct format.
at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
at System.String.System.IConvertible.ToDouble(IFormatProvider provider)
at System.Data.Common.DoubleStorage.Set(Int32 record, Object value)
at System.Data.DataColumn.set_Item(Int32 record, Object value)
--- End of inner exception stack trace ---
at System.Data.DataColumn.set_Item(Int32 record, Object value)
at System.Data.DataRow.set_ItemArray(Object[] value)
at Program.Main()
Command terminated by signal 6
using System;
using System.Data;
public class Program
{
public static void Main()
{
string sp="Bewohner;1102284;1102284;42600;ASG ROT;Menü (Inklusivleistung);01.07.2022;0;1;;;;;2000003^Bewohner2;11022842;11022824;426200;ASG2 ROT;Menü (Inklusivleistung);01.07.2022;0;1;;;;;2000004";
var dt = new DataTable();
Console.WriteLine("datatable success");
dt.Columns.Add(new DataColumn("description", typeof(String)));
dt.Columns.Add(new DataColumn("code", typeof(String)));
dt.Columns.Add(new DataColumn("cardnumber", typeof(String)));
dt.Columns.Add(new DataColumn("costcentrecode", typeof(int)));
dt.Columns.Add(new DataColumn("costcentre", typeof(String)));
dt.Columns.Add(new DataColumn("article_description", typeof(String)));
dt.Columns.Add(new DataColumn("trans_date", typeof(DateTime)));
dt.Columns.Add(new DataColumn("article_price", typeof(Double)));
dt.Columns.Add(new DataColumn("article_quantity", typeof(Double)));
dt.Columns.Add(new DataColumn("netto", typeof(Double)));
dt.Columns.Add(new DataColumn("brutto", typeof(Double)));
dt.Columns.Add(new DataColumn("mwst", typeof(Double)));
dt.Columns.Add(new DataColumn("beleg", typeof(Double)));
dt.Columns.Add(new DataColumn("oberverkaufsgruppe", typeof(int)));
dt.Columns.Add(new DataColumn("house", typeof(String)));
dt.Columns.Add(new DataColumn("id", typeof(String)));
string[] mainarray = sp.Split('^');
for(int a=0;a<mainarray.Length;a++)
{
string[] itemArray = mainarray[a].Split(';');
DataRow row = dt.NewRow();
for (int i = 0; i < itemArray.Length; i++)
{
if (string.IsNullOrWhiteSpace(itemArray[i]))
{
itemArray[i] = null;
}
}
row.ItemArray = itemArray; //doesnt work and throws ArgumentException
itemArray.CopyTo(row.ItemArray, 0); //doesnt work either
for (int i = 0; i < 14; i++) //also doesnt work and leaves it empty
{
row.ItemArray[i] = itemArray[i];
//Console.WriteLine(row.ItemArray[i]);
}
row["id"] = Guid.NewGuid().ToString();
row["house"] = "";
dt.Rows.Add(row);
}
foreach(DataRow dataRow in dt.Rows)
{var ix = 0;
foreach(var item in dataRow.ItemArray)
{
Console.WriteLine(ix+"-----"+item);
ix++;
}
}
}
}
OUTPUT :
datatable success
0-----Bewohner
1-----1102284
2-----1102284
3-----42600
4-----ASG ROT
5-----Menü (Inklusivleistung)
6-----01/07/2022 00:00:00
7-----0
8-----1
9-----
10-----
11-----
12-----
13-----2000003
14-----
15-----ccf0a446-610e-4396-896d-7e8c4a43f729
0-----Bewohner2
1-----11022842
2-----11022824
3-----426200
4-----ASG2 ROT
5-----Menü (Inklusivleistung)
6-----01/07/2022 00:00:00
7-----0
8-----1
9-----
10-----
11-----
12-----
13-----2000004
14-----
15-----0c9cb9b1-8640-4626-8790-0d80fad9d8da
I have a dataset where I am pulling value from the database, now after that, I want to add some more rows to it. I get four columns from the database: approverName, approverEmail, approverRole, approvalStatus
DataSet dsResult = new DataSet();
dsResult = getDataFromDatabase();
DataTable dt = new DataTable("MyTable");
dt.Columns.Add(new DataColumn("approverName", typeof(string)));
dt.Columns.Add(new DataColumn("approverEmail", typeof(string)));
dt.Columns.Add(new DataColumn("approverRole", typeof(string)));
dt.Columns.Add(new DataColumn("approvalStatus", typeof(string)));
DataRow dr = dt.NewRow();
dr["approverName"] = "John";
dr["approverEmail"] = "John#gc.com";
dr["approverRole"] = "Manager";
dr["approvalStatus"] = "Pending";
dt.Rows.Add(dr);
dsResult.Tables.Add(dt);
But after executing code I don't see this manually added value in the dataset. It only shows the value which I had after executing line 2 of code
You don't need to create another DataTable.
Append new row to existing DataTable
DataSet dsResult = new DataSet();
dsResult = getDataFromDatabase();
DataTable dt = dsResult.Tables[0]; //Get Reference to existing table
DataRow dr = dt.NewRow();
dr["approverName"] = "John";
dr["approverEmail"] = "John#gc.com";
dr["approverRole"] = "Manager";
dr["approvalStatus"] = "Pending";
dt.Rows.Add(dr);
i have an XML file which contain date & time like this
<date>3/24/2014</date>
<time>9:00 AM</time>
</playdate>
i store this data in a data set & want to add in data table. i write this code for getting data
DataRow dr = dt.NewRow();
dr["StartDate"] = ds.Tables[0].Rows[i][1].ToString();
dr["StartTime"] = ds.Tables[0].Rows[i][1].ToString();
But the problem is when i export data in excel file i got both date & time in excel file in same column. i want date in my StartDate & time in StartTime . how can i split XML data
EDIT
string url = #"c:\temp\TestXML.xml";
StreamReader reader = new StreamReader(url);
string input = reader.ReadToEnd();
input = input.Trim();
input = input.Replace("- <", " <");
input = input.Replace(" & ", " & ");
input = input.Replace("W&W", "W&W");
input = input.Replace("", "
");
int userid = 0;
int j = 1;
try
{
DataSet ds = new DataSet();
ds.ReadXml(new StringReader(input));
// Creating Data Table according to Table Value Parameter in Database
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("CalenderName", typeof(string)));
dt.Columns.Add(new DataColumn("EventName", typeof(string)));
dt.Columns.Add(new DataColumn("StartDate", typeof(DateTime)));
dt.Columns.Add(new DataColumn("EndDate", typeof(DateTime)));
dt.Columns.Add(new DataColumn("StartTime", typeof(DateTime)));
dt.Columns.Add(new DataColumn("EndTime", typeof(DateTime)));
dt.Columns.Add(new DataColumn("Venue", typeof(string)));
dt.Columns.Add(new DataColumn("Address", typeof(string)));
dt.Columns.Add(new DataColumn("City", typeof(string)));
dt.Columns.Add(new DataColumn("State", typeof(string)));
dt.Columns.Add(new DataColumn("ZipCode", typeof(string)));
dt.Columns.Add(new DataColumn("PhoneNo", typeof(string)));
dt.Columns.Add(new DataColumn("Link", typeof(string)));
dt.Columns.Add(new DataColumn("Email", typeof(string)));
dt.Columns.Add(new DataColumn("Performer", typeof(string)));
dt.Columns.Add(new DataColumn("Tags", typeof(string)));
dt.Columns.Add(new DataColumn("Price", typeof(string)));
dt.Columns.Add(new DataColumn("PriceURL", typeof(string)));
dt.Columns.Add(new DataColumn("EventDetails", typeof(string)));
dt.Columns.Add(new DataColumn("TimeZoneName", typeof(string)));
dt.Columns.Add(new DataColumn("TimeZoneOffsetAtCreation", typeof(int)));
dt.Columns.Add(new DataColumn("TabIndex", typeof(int)));
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
DataRow dr = dt.NewRow();
string sDate = ds.Tables[2].Rows[i][0].ToString();
string sTime = ds.Tables[2].Rows[i][1].ToString();
DateTime dDateTime;
//cond: for checking the datetime parsing
if (DateTime.TryParseExact(sDate, "m/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dDateTime))
{
//sDate = dDateTime.ToString("M/dd/yyyy");
//dr["StartDate"] = sDate;
dr["StartDate"] = dDateTime;
}
//cond: for checking the datetime parsing
if (DateTime.TryParseExact(sTime, "hh:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dDateTime))
{
//sTime = dDateTime.ToString("h:mm:ss");
//dr["StartTime"] = sTime;
dr["StartTime"] = dDateTime;
}
dr["EventName"] = ds.Tables[0].Rows[i][1].ToString();
//dr["StartDate"] = ds.Tables[2].Rows[i][0].ToString();
//dr["EndDate"] = ds.Tables[2].Rows[i][0].ToString();
//dr["StartTime"] = ds.Tables[2].Rows[i][1].ToString();
//dr["EndTime"] = ds.Tables[2].Rows[i][1].ToString();
dr["Venue"] = ds.Tables[1].Rows[i][1].ToString();
dr["Address"] = ds.Tables[1].Rows[i][2].ToString();
dr["City"] = ds.Tables[1].Rows[i][4].ToString();
dr["State"] = ds.Tables[1].Rows[i][5].ToString();
dr["ZipCode"] = Convert.ToInt32(ds.Tables[1].Rows[i][6].ToString());
dr["PriceURL"] = ds.Tables[0].Rows[i][2].ToString();
dr["EventDetails"] = ds.Tables[0].Rows[i][4].ToString();
dt.Rows.Add(dr);
j++;
}
gvXmlData.DataSource = dt;
gvXmlData.DataBind();
btnExportData.Visible = true;
try with DateTime.ParseExact
string cellValue = "3/31/2014 9:00:00 AM";// this can be a cell value from excel file like ds.Tables[0].Rows[i][1].ToString()
DateTime date = DateTime.ParseExact(
cellValue,
"M/dd/yyyy h:mm:ss tt",
CultureInfo.InvariantCulture);
string startDate = date.ToString("M/dd/yyyy");
string startTime = date.ToString("h:mm:ss tt");
You are accessing same cell value in both StartDate and StartTime.
Most probably next cell should give you time value.
Also you can format date time same as specified in XML e.g. (mm/dd/YYYY)
Same goes with time hours minutes and seconds.
see code example here:
string sDate = ds.Tables[0].Rows[i][0].ToString();
string sTime = ds.Tables[0].Rows[i][1].ToString();
DateTime dDateTime;
DataRow dr = dt.NewRow();
//cond: for checking the datetime parsing
if (DateTime.TryParseExact(sDate, "M/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dDateTime))
{
//sDate = dDateTime.ToString("M/dd/yyyy");
//dr["StartDate"] = sDate;
dr["StartDate"] = dDateTime;
}
//cond: for checking the datetime parsing
if (DateTime.TryParseExact(sTime, "hh:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dDateTime))
{
//sTime = dDateTime.ToString("h:mm:ss");
//dr["StartTime"] = sTime;
dr["StartTime"] = dDateTime;
}
public void BindGrid(int rowcount)
{
btnsubmit.Visible = true;
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Employee ID", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Leave Type", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("From", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("To", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("No:of Days", typeof(String)));
if (ViewState["CurrentData"] != null)
{
for (int i = 0; i < rowcount + 1; i++)
{
dt = (DataTable)ViewState["CurrentData"];
if (dt.Rows.Count > 0)
{
dr = dt.NewRow();
dr[0] = dt.Rows[0][0].ToString();
}
}
dr = dt.NewRow();
dr[0] = lblempID.Text;
dr[1] = ddlleavetype.SelectedItem.Text.ToString();
dr[2] = txtfrom.Text.ToString();
dr[3] = txtto.Text.ToString();
dt.Rows.Add(dr);
}
else
{
dr = dt.NewRow();
dr[0] = lblempID.Text;
dr[1] = ddlleavetype.SelectedItem.Text.ToString();
dr[2] = txtfrom.Text.ToString();
dr[3] = txtto.Text.ToString();
dt.Rows.Add(dr);
}
// If ViewState has a data then use the value as the DataSource
if (ViewState["CurrentData"] != null)
{
gvLeave.DataSource = (DataTable)ViewState["CurrentData"];
gvLeave.DataBind();
}
else
{
// Bind GridView with the initial data assocaited in the DataTable
gvLeave.DataSource = dt;
gvLeave.DataBind();
}
// Store the DataTable in ViewState to retain the values
ViewState["CurrentData"] = dt;
}
In my page having from date textbox and todate textbox..i want to calculate the between two dates ,please help me
I'm not very familiar with the DataTable object, so take this answer as an idea. :-)
Why don't you specify the Rows with the actual type?
dt.Columns.Add(new System.Data.DataColumn("From", typeof(DateTime)));
dt.Columns.Add(new System.Data.DataColumn("To", typeof(DateTime)));
dt.Columns.Add(new System.Data.DataColumn("No:of Days", typeof(int)));
And after this you can Parse the data of txtfrom like dr[2] = DateTime.Parse(txtfrom.Text.ToString()) and assign it to your DataRow. Same goes for txtto.
After this, you are able to calculate the days between by using:
dr[4] = (int)((dr[2] -dr[3]).TotalDays);
If this doesn't work, try to save the parsed Dates in objects like so:
DateTime from = DateTime.Parse(txtfrom.Text.ToString());
DateTime to = ...;
TimeSpan t1 = to - from;
dt[4] = (int)(t1.TotalDays);
If they are in a textbox you will need to parse them first using DateTime.Parse. This is under the assumption that the strings are in the correct format
DateTime myDate = DateTime.Parse(myDateString);
To calculate the days between two dates you can try this
TimeSpan span =date1-date2;
var days = span.TotalDays;
Try this Code :
Var Day= DateTime.Parse(todate.Text).Subtract(DateTime.Parse(fromdate.Text)).Days;
I have created a datatable and trying to insert that datatable through SqlBulkCopy but somehow it doesn't seem to work for me....
I got the error,
The given value of type DateTime from the data source cannot be converted
to type decimal of the specified target column.
My Datasource is,
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("EmpId", typeof(Int64)));
dt.Columns.Add(new DataColumn("FromDate", typeof(DateTime)));
dt.Columns.Add(new DataColumn("ToDate", typeof(DateTime)));
dt.Columns.Add(new DataColumn("DaysPresent", typeof(decimal)));
dt.Columns.Add(new DataColumn("OpeningAdvance", typeof(double)));
dt.Columns.Add(new DataColumn("AdvanceDeducted", typeof(double)));
dt.Columns.Add(new DataColumn("RemainingAdvance", typeof(double)));
dt.Columns.Add(new DataColumn("SalaryGiven", typeof(double)));
dt.Columns.Add(new DataColumn("CreatedDate", typeof(DateTime)));
foreach (GridViewRow row in gridEmployee.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
DataRow dr = dt.NewRow();
dr["EmpId"] = Convert.ToInt64(((HiddenField)row.Cells[0].FindControl("HiddenId")).Value);
dr["FromDate"] = Convert.ToDateTime(GetMonthNumberFromAbbreviation(fromdate[1].ToString()) + '/' + fromdate[0].ToString() + '/' + fromdate[2].ToString());
dr["ToDate"] = Convert.ToDateTime(GetMonthNumberFromAbbreviation(todate[1].ToString()) + '/' + todate[0].ToString() + '/' + todate[2].ToString());
dr["DaysPresent"] = Convert.ToDecimal(((TextBox)row.Cells[3].FindControl("TxtDaysPresent")).Text);
dr["OpeningAdvance"] = Convert.ToDouble(((TextBox)row.Cells[4].FindControl("txtOpeningAdv")).Text);
dr["AdvanceDeducted"] = Convert.ToDouble(((TextBox)row.Cells[5].FindControl("TxtAdvanceDeducted")).Text);
dr["RemainingAdvance"] = Convert.ToDouble(((TextBox)row.Cells[6].FindControl("TxtClosingAdvance")).Text);
dr["SalaryGiven"] = Convert.ToDouble(((TextBox)row.Cells[7].FindControl("TxtSalary")).Text);
dr["CreatedDate"] = Convert.ToDateTime(System.DateTime.Now.ToString());
dt.Rows.Add(dr);
}
}
SqlBulkCopy sbc = new SqlBulkCopy(connectionString);
sbc.DestinationTableName = "SalaryDetails";
sbc.WriteToServer(dt);
sbc.Close();
And my destination Table looks like this,
alt text http://img231.imageshack.us/img231/5448/mytable.jpg
You need to specify a column mapping, as you don't have the same number of columns in the DataTable and the destination table.
You can do it like this:
sbc.ColumnMappings.Add("EmpId", "EmpId");
sbc.ColumnMappings.Add("FromDate", "FromDate");
// and so on, with the rest of the columns; and after that comes
sbc.WriteToServer(dt);
sbc.Close();