I have read an excel file to a DataTable but only the first row fills the whole MS Access database. I have confirmed that the data in the DataTable and in the Excel file are the same. My code is shown below:
using (OleDbConnection myCon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + outFilePath + ";Extended Properties=dBase IV"))
{
OleDbCommand cmd = new OleDbCommand();
string line = "001";
for (int n = 0; n < dt.Rows.Count; ++n)
{
if (String.IsNullOrEmpty(dt.Rows[n].Field<string>(0))) break;
cmd.CommandText = "INSERT INTO " + FileName +
"([JNL],[LINE],[TYPE],[DRACC],[CRACC],[EXPDRACC],[EXPCRACC]," +
"[DOCDATE],[REF],[DRAMT],[CRAMT]) VALUES (?,?,?,?,?,?,?,?,?,?,?)";
string inacc = dt.Rows[n].Field<string>(0);
string justNumbers = new String(inacc.Where(Char.IsDigit).ToArray());
string acc = String.Format("{0:##-######-#}", justNumbers);
string jnl = JNL;
string Ref = REF;
string type = TYPE;
int dramt = 0;
int cramt = 0;
if (type == "50") dramt = Convert.ToInt32(100 * dt.Rows[n].Field < double>(2));
else cramt = Convert.ToInt32(100 * dt.Rows[n].Field < double>(2));
cmd.Parameters.Add("#JNL", OleDbType.VarChar).Value = jnl;
cmd.Parameters.Add("#LINE", OleDbType.VarChar).Value = line;
cmd.Parameters.Add("#TYPE", OleDbType.VarChar).Value = type;
cmd.Parameters.Add("#DRACC", OleDbType.VarChar).Value = justNumbers;
cmd.Parameters.Add("#CRACC", OleDbType.VarChar).Value = justNumbers;
cmd.Parameters.Add("#EXPDRACC", OleDbType.VarChar).Value = acc;
cmd.Parameters.Add("#EXPCRACC", OleDbType.VarChar).Value = acc;
cmd.Parameters.Add("#DOCDATE", OleDbType.Date).Value = DateTime.Now;
cmd.Parameters.Add("#REF", OleDbType.VarChar).Value = Ref;
cmd.Parameters.Add("#DRAMT", OleDbType.Integer).Value = dramt;
cmd.Parameters.Add("#CRAMT", OleDbType.Integer).Value = cramt;
cmd.CommandType = CommandType.Text;
cmd.Connection = myCon;
myCon.Open();
cmd.ExecuteNonQuery();
myCon.Close();
}
}
How to resolve this kind of issue?
You have to remove the parameters from your command. You are adding ever more parameters to it. Use
cmd.Parameters.Clear();
as first line of your for statement.
You add the first set of parameters and reuse the same command without clearing them, so you end up with a command that has n*11 (parameters defined/loop).
The first match in the collection is used to substitute your commands params so you get n Entries with same data.
Related
I've got the following code:
private void btnAddMatter_Click(object sender, EventArgs e)
{
MatterCode = "";
EntityID = 0;
FeeEarnerID = 0;
OpenedByUserID = 0;
CompanyContactDetailsID = 0;
Description = "";
OurReference = "";
TheirReference = "";
DateOpened = DateTime.Now;
MatterTypeID = 0;
DepartmentID = 0;
ResponsibleUserID = 0;
TrustBankAccountID = 0;
BusinessBankAccountID = 0;
string connectionString = "Data Source=***\\SQLEXPRESS;Initial Catalog=STUPELG;Persist Security Info=True;User ID=***;Password=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Matter ( MatterCode, EntityID, FeeEarnerID, OpenedByUserID, CompanyContactDetailsID, Description," +
" OurReference, TheirReference, DateOpened, MatterTypeID, DepartmentID, ResponsibleUserID, TrustBankAccountID, BusinessBankAccountID)" +
" VALUES ( #MatterCode, #EntityID, #FeeEarnerID, #OpenedByUserID, #CompanyContactDetailsID, #Description," +
" #OurReference, #TheirReference, #DateOpened, #MatterTypeID, #DepartmentID, #ResponsibleUserID, #TrustBankAccountID, #BusinessBankAccountID);" +
" SELECT SCOPE_IDENTITY();");
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#MatterID", MatterID);
cmd.Parameters.AddWithValue("#MatterCode", MatterCode);
cmd.Parameters.AddWithValue("#EntityID", EntityID);
cmd.Parameters.AddWithValue("#FeeEarnerID", FeeEarnerID);
cmd.Parameters.AddWithValue("#OpenedByUserID", OpenedByUserID);
cmd.Parameters.AddWithValue("#CompanyContactDetailsID", CompanyContactDetailsID);
cmd.Parameters.AddWithValue("#Description", Description);
cmd.Parameters.AddWithValue("#OurReference", OurReference);
cmd.Parameters.AddWithValue("#TheirReference", TheirReference);
cmd.Parameters.AddWithValue("#MatterTypeID", MatterTypeID);
cmd.Parameters.AddWithValue("#DepartmentID", DepartmentID);
cmd.Parameters.AddWithValue("#ResponsibleUserID", ResponsibleUserID);
cmd.Parameters.AddWithValue("#TrustBankAccountID", TrustBankAccountID);
cmd.Parameters.AddWithValue("#BusinessBankAccountID", BusinessBankAccountID);
cmd.Parameters.AddWithValue("#DateOpened", DateOpened);
connection.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID);
MatterCode = Convert.ToString(NewMatterID.Tables[0].Rows[0][0]);
}
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("UPDATE Matter SET MatterCode = #MatterCode WHERE MatterID = " + MatterCode);
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#MatterCode", MatterCode);
connection.Open();
cmd.ExecuteNonQuery();
}
MessageBox.Show("Matter " + MatterCode + " successfully created");
}
After the row is inserted, the new MatterID (primary key that is generated automatically) should be copied to the MatterCode field. Currently it works EXCEPT that there is an extra row that is generated at when the button is clicked:
How do I fix this???
Well - this is because your code is executing the INSERT query twice......
connection.Open();
cmd.ExecuteNonQuery(); // first execution
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID); // second execution
I'm not entirely sure what you wanted to do with that SqlDataAdapter - but it's using the same SqlCommand from before, with the INSERT statement, which gets executed a second time......
You can replace this:
cmd.ExecuteNonQuery();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID);
MatterCode = Convert.ToString(NewMatterID.Tables[0].Rows[0][0]);
with
MatterCode = cmd.ExecuteScalar().ToString();
as ExecuteScalar runs the command and returns the value of the first column of the first row of the first resultset.
My code:
DataTable dt = new DataTable();
mySqlDataAdapter.Fill(dt);
int socot = dt.Rows.Count;
for (int i = 0; i < socot; i++)
{
String dn = dt.Rows[i][1].ToString();
String gduan = "SELECT tennha FROM duannha WHERE id=#id";
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = gduan;
cmd.Parameters.AddWithValue("#id", dn);
String gtennha = cmd.ExecuteScalar().ToString();
dt.Rows[i][1] = gtennha;
}
When I run code, I received an error. Please help me fix it.
Expected Type as Int32
If gtennha contains a number, you can parse it to an int. With more safeguards:
var gtennha = cmd.ExecuteScalar();
try
{
if(gtennha != null)
dt.Rows[i][1] = int.Parse(gtennha.ToString());
else
Console.WriteLine("Error: Query didn't return a result.");
}
catch(FormatException ex)
{
Console.WriteLine("Error: Couldn't parse 'gtennha' to a number.");
/* more error handling */
}
Parse string to int
DataTable dt = new DataTable();
mySqlDataAdapter.Fill(dt);
int socot = dt.Rows.Count;
for (int i = 0; i < socot; i++)
{
String dn = dt.Rows[i][1].ToString();
String gduan = "SELECT tennha FROM duannha WHERE id=#id";
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = gduan;
cmd.Parameters.AddWithValue("#id", dn);
String gtennha = cmd.ExecuteScalar().ToString();
int a;
int.TryParse(gtennha, out a);
dt.Rows[i][1] = a;
}
Update
if gtennha always start with VIOFFICE or a word something like that then use this way split string
DataTable dt = new DataTable();
mySqlDataAdapter.Fill(dt);
int socot = dt.Rows.Count;
for (int i = 0; i < socot; i++)
{
String dn = dt.Rows[i][1].ToString();
String gduan = "SELECT tennha FROM duannha WHERE id=#id";
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = gduan;
cmd.Parameters.AddWithValue("#id", dn);
String gtennha = cmd.ExecuteScalar().ToString();
int a;
int.TryParse(gtennha.Split(' ')[1], out a);
dt.Rows[i][1] = a;
}
I think you have choosen the wrong column to assign the return value of your ExecuteScalar query. From your error message it is clear that the return value is a string "VI BUILDING 29BD" (or something like that) and you are trying to assing that value to the same column dt.Rows[i][1] that you have used as the source for the ID parameter. This of course cannot be correct.
So you need to identify what is the column that you want to assign the return value of the ExecuteScalar and take extra care on handling that return value that could be NULL if there is no match on the WHERE clause
DataTable dt = new DataTable();
mySqlDataAdapter.Fill(dt);
int socot = dt.Rows.Count;
for (int i = 0; i < socot; i++)
{
String dn = dt.Rows[i][1].ToString();
String gduan = "SELECT tennha FROM duannha WHERE id=#id";
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = gduan;
cmd.Parameters.AddWithValue("#id", dn);
object result = cmd.ExecuteScalar();
// SUPPOSE THAT YOU WANT TO ASSIGN AT COLUMN 2 NOT STILL AT COLUMN 1
if(result != null)
dt.Rows[i][2] = gtennha;
}
I'm traying to insert data into my microsoft database but this run time error is thrown
"Incorrect syntax near 'date'.\r\nMust declare the scalar variable \"#\"."
in this line Cmd.ExecuteNonQuery();
here is my code
public void InsertInventory(DateTime _date, int _customer_Id,
int _employee_Id, List<int> _product_Id,
List<int> _amountSold,
List<int> _unitPrice, List<int> _totalPrice)
{
Connection_String = #"Data Source=MOSTAFA-PC;Initial Catalog="
+ "Sales and Inventory System"
+ ";Integrated Security=TrueData Source=MOSTAFA-PC;Initial Catalog="
+ "Sales and Inventory System"
+ ";Integrated Security=True;";
Query = "insert into Inventory" +
"(Customer_Id,Employee_Id,Product_Id,[Date],[Amount Sold],[Unit Price],[Total Price])" +
"values (#customer_id,#Employee_id,#Product_id,#[Date],#[Amount_Sold],#[Unit_Price],#[Total_Price])";
using (Con = new SqlConnection(Connection_String))
using (Cmd = new SqlCommand(Query, Con))
{
Cmd.Parameters.Add("#customer_id", SqlDbType.Int);
Cmd.Parameters.Add("#Employee_id", SqlDbType.Int);
Cmd.Parameters.Add("#Product_id", SqlDbType.Int);
//Cmd.Parameters.Add("#[Date]", SqlDbType.NVarChar);
Cmd.Parameters.Add("#[Date]", SqlDbType.Date);
Cmd.Parameters.Add("#[Amount_sold]", SqlDbType.Int);
Cmd.Parameters.Add("#[Unit_Price]", SqlDbType.Decimal);
Cmd.Parameters.Add("#Total_Price", SqlDbType.Decimal);
Cmd.Connection = Con;
Con.Open();
int RecordToAdd = _product_Id.Count;
for (int i = 0; i < RecordToAdd; i++)
{
Cmd.Parameters["#customer_id"].Value = _customer_Id;
Cmd.Parameters["#Employee_id"].Value = _employee_Id;
Cmd.Parameters["#[Date]"].Value = _date;
Cmd.Parameters["#Product_id"].Value = _product_Id[i];
Cmd.Parameters["#[Amount_sold]"].Value = _amountSold[i];
Cmd.Parameters["#[Unit_Price]"].Value = _unitPrice[i];
Cmd.Parameters["#Total_Price"].Value = _totalPrice[i];
Cmd.ExecuteNonQuery();
}
}
what should i do?
for the parameter names, you don't need to wrap with [] you can just use #Date, #AmountSold, #UnitPrice, #TotalPrice. Just make sure you fix them in both the statement and the parameter lists
I have a 4 text boxes on a win form. [First Name, Last Name, Job, Description.]
I have one table.
I have the dataset and a data table configured and I can navigate the records.
I want to know how can I search based on first name, obtain the data from dataset/table and display the info based on what is in the text box.
how do I do this such as, obtain the row, "inc" where the
txtFirstName = ds.Tables[0].Column[1]
Then I can:
DataRow row = ds.Tables[0].Rows[inc];
txtFirstName.Text = row[1];
txtSurname.Text = row[2];
txtJobTitle.Text = row[3];
txtDepartment.Text = row[4];
sorry, found the solution.
First I created a search method which returned the row...
private int first_name_search(string fname)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
if ((string)ds.Tables[0].Rows[i]["first_name"] == fname)
{
send = i;
//result stuff
break;
}
}
// return result;
return send;
}
I used this method in the Search button click method and displayed the data...
In a function that return a string[]:
string[number_of_infos] infos = null;
connection = new SqlConnection(connectionString);
connection.Open();
cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM your_table WHERE first_name = " + your_first_name;
cmd.Connection = connection;
rdr = cmd.ExecuteReader();
if(rdr.Read())
{
infos[0] = rdr["Surname"].ToString();
infos[1] = rdr["JobTitle"].ToString();
infos[2] = rdr["Department"].ToString();
}
cmd.Dispose();
connection.Close();
return infos;
Direct in your form:
connection = new SqlConnection(connectionString);
connection.Open();
cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM your_table WHERE first_name = " + your_first_name;
cmd.Connection = connection;
rdr = cmd.ExecuteReader();
if(rdr.Read())
{
txtSurname.Text = rdr["Surname"].ToString();
txtJobTitle.Text = rdr["JobTitle"].ToString();
txtDepartment.Text = rdr["Department"].ToString();
}
cmd.Dispose();
connection.Close();
return infos;
Else if you want to get the row infos:
foreach(DataGridViewRow row in your_DGV.Rows)
if(row["FirstName"].Value.ToString() == txtFirstName.Text)
{
txtSurname.Text = row["Surname"].Value.ToString();
txtJobTitle.Text = row["JobTitle"].Value.ToString();
txtDepartment.Text = row["Department"].Value.ToString();
break;
}
FYI, you can use LINQ extensions to do this:
var tbl = ds.Tables[0].AsEnumerable();
return tbl.Where(p => p["first_name"] == fname).FirstOrDefault();
Edit: To select all matching rows from the DataTable:
var results = from row in tbl.AsEnumerable()
where row["first_name"] == fname
select row;
i need update some column in datagridview to database. but don't update to database.
step one: i select datetime from datetimepicker.
step two: show datetime on datagridview.
step tree: i need update/edit on datagridview to database.
Display on Datagridview.
EmpNo fName ChkDate ChkIn ChkOut
00001 Al 01/10/2012 08:02 17:04
00002 Bik 01/10/2012 07:43 18:35
i need update fields "ChkIn" to database.
Code
SqlConnection Conn;
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da;
DataTable dt = new DataTable();
DataSet ds = new DataSet();
StringBuilder sb = new StringBuilder();
string appConn = ConfigurationManager.ConnectionStrings["connDB"].ConnectionString;
int i;
for (i = 1; i < dgvShow.Rows.Count; i++)
{
if (dgvShow.Rows.Count > 0)
{
SqlConnection conn = new SqlConnection(appConn);
string sql = "UPDATE [WebSP].[dbo].[filesTA]"
+ "SET [filesTA].ChkIn = replace(convert(nvarchar(10),'" + dgvShow.Rows[i].Cells[3].Value + "',102),'.',':')"
+ "FROM [WebSP].[dbo].[filesTA]"
+ "WHERE [filesTA].ChkDate = '" + dateTimePicker.Value.ToString("yyyy-MM-dd") + "' and [filesTA].EmpNo = '" + dgvShow.Rows[i].Cells[0].Value + "'";
da = new SqlDataAdapter(sql, Conn);
DataSet ds = new DataSet();
da.Fill(ds);
Conn.Close();
dgvShow.DataSource = ds;
da.Update(ds);
}
}
Error: Update unable to find TableMapping['Table'] or DataTable 'Table'.
I try other code:
Conn = new SqlConnection();
if (Conn.State == ConnectionState.Open)
{
Conn.Close();
}
Conn.ConnectionString = appConn;
Conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM [filesTA]", appConn);
adapter.UpdateCommand = new SqlCommand("UPDATE [WebSP].[dbo].[filesTA]"
+ "SET [filesTA].ChkIn = replace(convert(nvarchar(10),#cIn,102),'.',':')"
+ "FROM [WebSP].[dbo].[filesTA]"
+ "WHERE [filesTA].ChkDate = #cDate and [filesTA].EmpNo = #eNo", Conn);
adapter.UpdateCommand.Parameters.Add("#cIn", SqlDbType.NVarChar, 10, "ChkIn");
adapter.UpdateCommand.Parameters.Add("#cDate", SqlDbType.NVarChar, 10, "ChkDate");
adapter.UpdateCommand.Parameters.Add("#eNo", SqlDbType.NVarChar, 10, "EmpNo");
DataSet ds = new DataSet();
adapter.Fill(ds);
dgvShow.DataSource = ds;
adapter.Update(ds);
this code not save to database.
Thanks for your time. :D
Type Database:
ChkIn and ChkDate Type DateTime,EmpNo Type NUMERIC
I try
int i;
for (i = 1; i < dgvShow.Rows.Count; i++)
{
if (dgvShow.Rows.Count > 0)
{
using (Conn = new SqlConnection(appConn))
{
Conn.Open();
string sql = "UPDATE [WebSP].[dbo].[filesTA]" +
"SET [filesTA].ChkIn = replace(convert(nvarchar(10),#cIn,102),'.',':')" +
"FROM [WebSP].[dbo].[filesTA]" +
"WHERE [filesTA].ChkDate = #cDate and [filesTA].EmpNo = #eNo";
SqlCommand cmd = new SqlCommand(sql, Conn);
cmd.Parameters.Add("#cIn", SqlDbType.DateTime, 10, "ChkIn").Value = Convert.ToDateTime(dgvShow.Rows[i].Cells[3].Value).ToString();
cmd.Parameters.Add("#cDate", SqlDbType.DateTime, 10, "ChkDate").Value = Convert.ToDateTime(dateTimePicker.Value.ToString()).ToString();
cmd.Parameters.Add("#eNo", SqlDbType.Decimal, 10, "EmpNo").Value = Convert.ToDecimal(dgvShow.Rows[i].Cells[0].Value).ToString();
cmd.ExecuteNonQuery();
}
}
}
Error: Conversion failed when converting date and/or time from character string. T__T
You could try to get rid of the SqlDataAdapter using directly a SqlCommand
Using(Conn = new SqlConnection(appConn))
{
Conn.Open();
string sql = "UPDATE [WebSP].[dbo].[filesTA] " +
"SET [filesTA].ChkIn = replace(convert(nvarchar(10),#cIn,102),'.',':') " +
"FROM [WebSP].[dbo].[filesTA] " +
"WHERE [filesTA].ChkDate = #cDate and [filesTA].EmpNo = #eNo";
SqlCommand cmd = new SqlCommand(sql, Conn);
cmd.Parameters.Add("#cIn", SqlDbType.NVarChar, 10, "ChkIn").Value =
dgvShow.Rows[i].Cells[3].Value;
cmd.Parameters.Add("#cDate", SqlDbType.NVarChar, 10, "ChkDate").Value =
dateTimePicker.Value.ToString("yyyy-MM-dd") ;
cmd.Parameters.Add("#eNo", SqlDbType.NVarChar, 10, "EmpNo").Value =
dgvShow.Rows[i].Cells[0].Value ;
cmd.ExecuteNonQuery();
}
Of course, when using parameters, we need to set their values before running the command.
However I really don't understand well the code to update the ChkIn field. That field (according to the Parameter type) is a nvarchar, then why don't you try to format your #cIn value directly in code and avoid the use of Sql Server Replace and Convert functions? Also the 102 is a Date Style. It is used to format Date expressions as strings with the yy.mm.dddd pattern, but you have a string that contains only time info.
For example
After your last edit - changed to this
DateTime chkIN = Convert.ToDateTime(dgvShow.Rows[i].Cells[3].Value);
DateTime chkDate = Convert.ToDateTime(dateTimePicker.Value.ToString("yyyy-MM-dd"));
decimal empNo = Convert.ToDecimal(dgvShow.Rows[i].Cells[0].Value) ;
cmd.Parameters.Add("#cIn", SqlDbType.DateTime).Value = chkIN;
cmd.Parameters.Add("#cDate", SqlDbType.DateTime).Value = chkDate;
cmd.Parameters.Add("#eNo", SqlDbType.Decimal).Value = empNo;
Also the syntax used in query could be the source of other problems, but I need to see your connection string.