I have a some data that should be inserted into 4 tables one of these data are stored in data grid view selected rows , so I would loop through the data grid view selected rows to insert them into database I also used a method that do transaction and takes the SqlCommands as matrix and then proceed them one by one , but when I try to insert data it gives me the exception "Index was out of range. Must be non-negative and less than the size of the collection." in this line
cm[i].Parameters.Add("#car", Convert.ToInt32(newCarAdCarDgv.Rows[i].Cells[0].Value.ToString()));
This is the transaction method:
public void ExTr(SqlCommand[] cm)
{
if (cn.State == ConnectionState.Closed)
{
cn.Open();
}
SqlTransaction tr = cn.BeginTransaction();
for (int x = 0; x < cm.Length; x++)
{
cm[x].Connection = cn;
cm[x].Transaction = tr;
}
try
{
for (int x = 0; x < cm.Length; x++)
{
cm[x].ExecuteNonQuery();
}
tr.Commit();
MessageBox.Show("تمت عملية إضافة البيانات بنجاح");
}
catch (SqlException ex)
{
tr.Rollback();
MessageBox.Show(ex.Message);
}
finally
{
if (cn.State == ConnectionState.Open)
{
cn.Close();
}
}
}
And this is the code for insertion:
private void newAdSaveBtn_Click(object sender, EventArgs e)
{
try
{
count = newCarAdCarDgv.SelectedRows.Count + 3;
if (cn.State == ConnectionState.Closed)
{
cn.Open();
}
newCarAdClientPhoneTxt_Leave(sender, e);
newCarAdClientEmailTxt_Leave(sender, e);
newCarAdNotesTxt_Leave(sender, e);
SqlCommand[] cm = new SqlCommand[count];
cm[0] = new SqlCommand("insert into clientData (Id,clientName,clientWork,clientPhone,clientMobile,clientEmail) values (#id,#name,#work,#phone,#mobile,#email)", cn);
cm[0].Parameters.AddWithValue("#id", id);
cm[0].Parameters.AddWithValue("#name", newCarAdClientNameTxt.Text.Trim());
cm[0].Parameters.AddWithValue("#work", newCarAdClientWorkTxt.Text.Trim());
cm[0].Parameters.AddWithValue("#phone", newCarAdClientPhoneTxt.Text.Trim());
cm[0].Parameters.AddWithValue("#mobile", newCarAdClientMobileTxt.Text.Trim());
cm[0].Parameters.AddWithValue("#email", newCarAdClientEmailTxt.Text.Trim());
cm[1] = new SqlCommand("insert into marketingData (m_Id,marketingDurations,marketingStartsFrom,marketingEndsIn,notes,adDate) values (#id,#durations,#start,#end,#notes,#date)", cn);
cm[1].Parameters.AddWithValue("#id", id);
cm[1].Parameters.AddWithValue("#durations", newCarAdAdDurationTxt.Text.Trim());
cm[1].Parameters.AddWithValue("#start", newCarAdStartDayDtp.Value);
cm[1].Parameters.AddWithValue("#end", newCarAdEndDayDtp.Value);
cm[1].Parameters.AddWithValue("#notes", newCarAdNotesTxt.Text.Trim());
cm[1].Parameters.AddWithValue("#date", newCarAdDateDtp.Value);
cm[2] = new SqlCommand("insert into priceAndProfits (p_Id,marketingCost,marketingPrice,marketingProfit,dollarPrice) values (#id,#cost,#price,#profit,#dollar)", cn);
cm[2].Parameters.AddWithValue("#id", id);
cm[2].Parameters.AddWithValue("#cost", newCarAdCostTxt.Text.Trim());
cm[2].Parameters.AddWithValue("#price", newCarAdPriceTxt.Text.Trim());
cm[2].Parameters.AddWithValue("#profit", newCarAdProfitTxt.Text.Trim());
cm[2].Parameters.AddWithValue("#dollar", newCarAdDollarPriceTxt.Text.Trim());
for (int i = 3; i <= newCarAdCarDgv.SelectedRows.Count + 3; i++)
{
cm[i] = new SqlCommand("insert into carWorkCount (c_Id,carId) value (#id,#car)", cn);
cm[i].Parameters.Add("#id", id);
cm[i].Parameters.Add("#car", Convert.ToInt32(newCarAdCarDgv.Rows[i].Cells[0].Value.ToString()));
}
ExTr(cm);
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
Change the final loop to
for (int i = 0; i < newCarAdCarDgv.SelectedRows.Count; i++)
{
cm[i+3] = new SqlCommand("insert into carWorkCount (c_Id,carId) value (#id,#car)", cn);
cm[i+3].Parameters.Add("#id", id);
cm[i+3].Parameters.Add("#car",
Convert.ToInt32(newCarAdCarDgv.SelectedRows[i].Cells[0].Value.ToString()));
}
Your code refers to Rows[i] but i starts with value 3 and you can go out of the number of rows if you select all the rows in your grid. Instead you just need to reference the commands with i+3
Related
protected void Btn_CheckOut_Click(object sender, EventArgs e)
{
int result = 0;
Payment user = new Payment(txt_CardNumber.Text, txt_CardHolderName.Text, txt_ExpirationDate.Text, txt_Cvv.Text);
result = ProductInsert();
/* Session["CardNumber"] = txt_CardNumber.Text;
Session["CardHolderName"] = txt_CardHolderName.Text;
Session["ExpirationDate"] = txt_ExpirationDate.Text;
Session["Cvv"] = txt_Cvv.Text;*/
Response.Redirect("Payment Sucessful.aspx");
}
public int ProductInsert()
{
int result = 0;
string queryStr = "INSERT INTO CustomerDetails(CardNumber, CardHolderName, ExpirationDate, Cvv)"
+ "values (#CardNumber,#CardHolderName, #ExpirationDate, #Cvv)";
try
{
SqlConnection conn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("#CardNumber", this.CardNumber);
cmd.Parameters.AddWithValue("#CardHolderName", this.CardHolderName);
cmd.Parameters.AddWithValue("#ExpirationDate", this.ExpirationDate);
cmd.Parameters.AddWithValue("#Cvv", this.Cvv);
conn.Open();
result += cmd.ExecuteNonQuery(); // Returns no. of rows affected. Must be > 0
conn.Close();
return result;
}
catch (Exception ex)
{
return 0;
}
}
}
I am trying to store credit card informations into database. I have created a productInsert() method and now I am trying to insert whatever values into the database.
This code is giving the error:
ProductInsert() does not exist in current context
When i use the code below,it does delete a row from a datagridview but when i refresh the page it does not..
private void DeleteData_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Selected)
{
dataGridView1.Rows.RemoveAt(row.Index);
break;
}
using (SqlConnection sqcon = new SqlConnection(#"MY CONNECTION STRING"))
{
SqlCommand Scmd = new SqlCommand();
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DataGridViewRow delrow = dataGridView1.Rows[i];
if (delrow.Selected == true)
{
dataGridView1.Rows.RemoveAt(i);
try
{
Scmd.CommandText = "DELETE FROM Technican WHERE ID=" + (i++) + "";
sqcon.Open(); //ADDED
int count = Scmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
}
What should i use to delete row from both local database and datagridview?
i think the connection not be assigned to the command object.
SqlCommand Scmd = new SqlCommand();
Scmd.Connection = sqcon;
also i preferred to use DataGridView.SelectedRows instead of looping all records in grid.
full code
private void DeleteData_Click(object sender, EventArgs e)
{
var rowsToDelete = dataGridView1.SelectedRows;
using (SqlConnection sqcon = new SqlConnection(#"MY CONNECTION STRING"))
{
SqlCommand Scmd = new SqlCommand();
Scmd.Connection = sqcon;
sqcon.Open(); //ADDED
foreach (DataGridViewRow row in rowsToDelete)
{
try
{
Scmd.CommandText = "DELETE FROM Technican WHERE ID=" + row.Cells["Id"].Value.ToString() + "";
int count = Scmd.ExecuteNonQuery();
dataGridView1.Rows.Remove(row);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
sqcon.Close();
}
}
Try this,
Delete from database use the unique column or the Id column.
//Make datagridview cell[0] the unique column in your table.
try
{
Scmd.CommandText = "DELETE FROM Technican WHERE ID='" + datagridview.rows[i].cell[0].value + "'";
sqcon.Open(); //ADDED
int count = Scmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
try
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["DeathWish"].ToString();
con.Open();
string query = string.Format("Select [ID],Decision from Data where [ID]='{0}' order by Decision", textBox1.Text);
SqlCommand cmd = new SqlCommand(query,con);
SqlDataReader dr = cmd.ExecuteReader();
string[] s = new string[] { };
while (dr.Read())
{
s = dr["Decision"].ToString().Split(',');
}
int length = s.Length;
for (int i = 0; i < length - 1; i++)
{
string fetr = s[i];
for (int j = 0; j <= checkedListBox1.Items.Count - 1; j++)
{
if (checkedListBox1.Items[j].ToString() == s[i])
{
checkedListBox1.SetItemChecked(j, true);
break;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.ToString());
}
}
string query = string.Format("Select [ID],Decision from Data where [ID]='{0}' order by Decision", textBox1.Text); is the line with error.
2nd picture edited* I wanted to retrieve a specific value on the database using checkedboxlist
this is the image:
error msg
i wanted to retrieve the data on the database and show the specific value
So a couple of things:
Consider enclosing your DB access code in a using block, and instantiating a new connection using your connection string. This ensures that - either by error or by completion of the block - the connection is correctly closed and disposed off.
Secondly, moving the try/catch inside of the using statement is good practice if you're also working with transactions, as you can commit on completion or rollback in your catch block.
Finally, never use string concatenation to build your queries, when the source of the data you're concatenating with comes from a user control (hell, just never do it). SQL injection is still the OWASP number 3 security risk in software to this day, and it needs to be squashed.
Mandatory reading:
OWASP - Top 10 Web Application Security Risks
SQL Injection - Wikipedia
SQL Injection - Technet
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
// a SqlConnection enclosed in a `using` statement will auto-close, and will ensure other resources are correctly disposed
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DeathWish"].ToString()))
{
try
{
con.Open()
string[] s = new string[] { };
string query = "Select [ID],Decision from Data where [ID]=#id order by Decision";
SqlCommand cmd = new SqlCommand(query, con);
SqlParameter idParam = new SqlParameter();
idParam.ParameterName = "#id";
idParam.Value = textBox1.Text;
cmd.Parameters.Add(idParam);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
s = dr["Decision"].ToString().Split(',');
}
int length = s.Length;
for (int i = 0; i < length - 1; i++)
{
string fetr = s[i];
for (int j = 0; j <= checkedListBox1.Items.Count - 1; j++)
{
if (checkedListBox1.Items[j].ToString() == s[i])
{
checkedListBox1.SetItemChecked(j, true);
break;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.ToString());
}
}
}
}
Your Connection is (still) open, so you have to check if it is closed. If it is you can open a new connection.
So try this:
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
try
{
if(con.State == ConnectionState.Closed)
{
con.Open();
}
con.ConnectionString = ConfigurationManager.ConnectionStrings["DeathWish"].ToString();
string query = string.Format("Select [ID],Decision from Data where [ID]='{0}' order by Decision", textBox1.Text);
SqlCommand cmd = new SqlCommand(query,con);
SqlDataReader dr = cmd.ExecuteReader();
string[] s = new string[] { };
while (dr.Read())
{
s = dr["Decision"].ToString().Split(',');
}
int length = s.Length;
for (int i = 0; i < length - 1; i++)
{
string fetr = s[i];
for (int j = 0; j <= checkedListBox1.Items.Count - 1; j++)
{
if (checkedListBox1.Items[j].ToString() == s[i])
{
checkedListBox1.SetItemChecked(j, true);
break;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.ToString());
}
}
I want to Change Quantity value within Datagridview, it will change price also. how it is possible? which event is for it using C# windows form.CellEndEdit already used by other cell(productname).
private void dataGridViewSalesForm_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
string MatchingProduct = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
for (int i = 0; i < objArrayList.Count; i++)
{
if (objArrayList[i].ToString().ToLower().StartsWith(MatchingProduct.ToLower()))
{
dataGridViewSalesForm.Rows[0].Cells[1].Value = objArrayList[i].ToString();
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading brandname from brandtable*/
string get_strProductName = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
string quantity = "1";
SqlConnection conn = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT T_Inv_Brands.brand_name FROM T_Inv_Products INNER JOIN T_Inv_Brands ON T_Inv_Products.brand_id = T_Inv_Brands.brand_id WHERE T_Inv_Products.prod_name ='" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridViewSalesForm.Rows[0].Cells[2].Value = ds.Tables[0].Rows[0]["brand_name"].ToString();
dataGridViewSalesForm.Rows[0].Cells[3].Value = quantity;
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading retailprice from producttable*/
SqlConnection connection = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT retailprice FROM T_Inv_Products WHERE prod_name = '" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, connection);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridViewSalesForm.Rows[0].Cells[4].Value = Convert.ToDouble(dt.Rows[0]["retailprice"].ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//double quantityload = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[3].Value.ToString());
//double pricefetch = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[4].Value.ToString());
//double result = quantityload * pricefetch;
//dataGridViewSalesForm.Rows[0].Cells[4].Value = result.ToString();
}
You seem to think that you can use an event for one cell or column only. Instead you need to code your events in such a way that all necessary cells and/or columns get their own piece of logic.
It helps to partition your code into smaller pieces with helpful names that document the logic they contain!
Here is an example with two branches, one for a certain cell and one for a certain column. I pass out the DataGridViewCellEventArgs so the functions can access the DataGridView DGV just as the real event can.. Of course you can expand on it as needed:
int quantityColumnIndex = 3; // use your own numbers..
int currencyColumnIndex = 1; // ..and names!!
int currencyRowIndex = 0;
int pricePerUnitColumnIndex = 7;
int totalPriceColumnIndex = 8;
int totalBasePriceColumnIndex = 4;
private void DGV_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == quantityColumnIndex) doPriceCalc(e);
else if (e.ColumnIndex == currencyColumnIndex && e.RowIndex == currencyRowIndex)
doAllCalc(e);
}
void doPriceCalc(DataGridViewCellEventArgs e)
{
// 1st example
DGV[totalPriceColumnIndex, e.RowIndex].Value =
(int)DGV[quantityColumnIndex, e.RowIndex].Value *
(decimal)DGV[pricePerUnitColumnIndex, e.RowIndex].Value;
}
void doAllCalc(DataGridViewCellEventArgs e)
{
// 2nd example
decimal currency = (decimal) DGV[currencyColumnIndex,currencyRowIndex ].Value;
for (int row = 0; row < DGV.Rows.Count; row++)
DGV[pricePerUnitColumnIndex, e.RowIndex].Value =
(decimal)DGV[totalBasePriceColumnIndex, e.RowIndex].Value * currency;
}
Note that I have indexed the columns by their indeices. You may just as well index them by their names, e.g.: DGV[ "PricePerUnit", e.rowIndex]
I have a problem in listview.I my listview i have five columns(question_number,question_text,start_time,end_time,status). the first four columns will be fetch the data from the database.once the data has entered i have to compare the starttime and with the current time.once the starttime is greater than current time then i have to update the status column as expired. otherwise i have to say not expired.
I have attached the code what i did so for.
I do no how to get the status updated in the status column.Please any one help me.thanks in advance.
public void GetData()
{
try
{
myConnection = new SqlConnection(#"User ID=sa;Password=password123;Initial Catalog=dish;Persist Security Info=True;Data Source=ENMEDIA-CCDDFE5\ENMEDIA");
//myConnection.Open();
//SqlDataReader dr = new SqlCommand("SELECT question_text,question_id FROM otvtbl_question ", myConnection).ExecuteReader();
// listView1.Columns.Clear();
listView1.Items.Clear();
myConnection.Open();
String MyString1 = string.Format("SELECT question_id,question_text,start_time,end_time FROM otvtbl_question");
SqlCommand cmd = myConnection.CreateCommand();
cmd.CommandText = MyString1;
dr = cmd.ExecuteReader();
//Adding The Column Name From The DataBase
for (int i = 0; i < dr.FieldCount; i++)
{
ColumnHeader ch = new ColumnHeader();
ch.Text = dr.GetName(i);
//listView1.Columns.Add(ch);
}
ListViewItem itmX;
//Adding the Items To The Each Column
while (dr.Read())
{
itmX = new ListViewItem();
itmX.Text = dr.GetValue(0).ToString();
for (int i = 1; i < dr.FieldCount; i++)
{
itmX.SubItems.Add(dr.GetValue(i).ToString());
}
listView1.Items.Add(itmX);
}
dr.Close();
myConnection.Close();
}
catch (Exception ex)
{
//Error Message While Fetching
MessageBox.Show("Error While Fetching the data From the DataBase" + ex);
}
finally
{
//Closing The Connection
if (dr != null)
dr.Close();
if (myConnection.State == ConnectionState.Open)
myConnection.Close();
}
Something like this?
while (dr.Read())
{
...
listView1.Items.Add(itmX);
if (dr.GetDateTime(2) > dr.GetDateTime(3))
{
itmX.SubItems.Add("Expired");
}
}