I am receiving this sql error there is no row at position - 1.
This is what I have done.
void showData(int index)
{
Connection con = new OrderManager.Connection();
SqlDataAdapter sda = new SqlDataAdapter("Select * from [MasterDatabase].[dbo].[Neworder] Where OrderID = '" + TxtBox_OrderID.Text + "'", con.ActiveCon());
dt = new DataTable();
sda.Fill(dt);
TxtBox_OrderID.Text = dt.Rows[index][0].ToString();
ClearTextBoxes();
dataGridView1.Rows.Clear();
foreach (DataRow item in dt.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item["OrderID"].ToString();
dataGridView1.Rows[n].Cells[1].Value = item["Date"].ToString();
dataGridView1.Rows[n].Cells[2].Value = item["Customer_Name"].ToString();
dataGridView1.Rows[n].Cells[3].Value = item["ProductID"].ToString();
dataGridView1.Rows[n].Cells[4].Value = item["Product_Name"].ToString();
dataGridView1.Rows[n].Cells[5].Value = item["Product_Color"].ToString();
dataGridView1.Rows[n].Cells[6].Value = item["Product_PCs"].ToString();
dataGridView1.Rows[n].Cells[7].Value = item["Product_Cutting"].ToString();
dataGridView1.Rows[n].Cells[8].Value = item["Product_TotalYards"].ToString();
}
label12.Text = "Row Count: " + dt.Rows.Count.ToString();
}
I want to display only those records while navigating whose OrderID is equals to the order ID in the database.
I think your error happens on this line
TxtBox_OrderID.Text = dt.Rows[index][0].ToString();
this is not an SQL error but a simple index out of the bounds of the array.
For some reasons, when you try to use a row that is not included in the Rows collection of the datatable you get this error message instead of the less ambiguous IndexOutOfRangeException. This message comes if you pass some value for the index variable that is less than zero or bigger than the number of rows in the datatable dt.
You don't have any check on the number of rows returned by the query and thus is possible that your query doesn't return any record or simple the value of index is -1
void showData(int index)
{
Connection con = new OrderManager.Connection();
SqlDataAdapter sda = new SqlDataAdapter(".......", con.ActiveCon());
dt = new DataTable();
sda.Fill(dt);
// Protect the access to the rows collection of the table...
if(index < dt.RowsCount && index >= 0)
{
TxtBox_OrderID.Text = dt.Rows[index][0].ToString();
// the code that fills the datagrid
}
else
{
// Message for your user about a record not found
}
}
As a side note, please follow ASAP the advice given to parameterize your query. You will avoid Sql Injection and parsin problems
My problem is that:
I want to Select one row from the database, The data should be arrange in expiry (the ones that are not yet expired and I don't want to limit it). The items that passed the current date must be left alone. And with all the same ITEMID lets say I00001.
Then after selecting I want to Update the first row of the database. if the quantity reaches 0 then it will go the next row to update and so on.
Here is my example
Here is the current database screenshot.
I want select the itemid where = I00001 and deduct 50.
Then it should look like this
Then I want to arrange based on the expiry as I mentioned above.
Select the first row.
Deduct the 50 from the quantity. (as I also mentioned above).
Here is my code:
for (int i = 0; i < dataGridView.Rows.Count; i++)
{
cmd = new MySqlCommand(#"SELECT * FROM inventory2 WHERE itemid = #itemid ORDER BY expiry ", sqlconnection);
cmd = new MySqlCommand(#"UPDATE inventory2 SET quantity = #quantity WHERE itemid = #itemid ORDER BY expiry)", sqlconnection);
sqlconnection.Open();
cmd.ExecuteNonQuery();
sqlconnection.Close();
}
I'm open for another suggestion in doing this. I hope you understand my problem. Thank you very much. I'm sorry I cannot send another screenshot.
Try this,
void UpdateQuantity() {
// your connection string
MySqlDataAdapter adp = new MySqlDataAdapter("Select * from table where ItemID = " + 13 + " Order BY expiry", cnn); // I have test db and I used it
DataTable dt = new DataTable();
adp.Fill(dt);
int deductNum = 50;
foreach (DataRow item in dt.Rows)
{
int value = (int)item["quantity"];
if (value >= deductNum) // if had enough stock we don't need to pass the next line
{
int result = value - deductNum;
item["quantity"] = result.ToString();
break; // so need to exit from loop
}
else
{
deductNum -= value; // else we deduct value count from deduction
item["quantity"] = 0; // quantity finished so it will be 0
}
}
MySqlCommandBuilder cmb = new MySqlCommandBuilder(adp);
adp.UpdateCommand = cmb.GetUpdateCommand();
adp.Update(dt);
dataGridView1.DataSource = dt; //to show the result
}
(You can calculate :))
Hope helps,
Please help I can't understand about variable for query by when in SQL command. -> get value and do loop again and again (get and change) sorry I'm not good english
This code :
var ee = 0;
var command = new SqlCommand("SELECT Values,date FROM db_db where date ='" + ee ", connection);
var reader = command.ExecuteReader();
var dt = 8;
for (int i = 0; i <= dt; i++)
{
dataGridView1.Columns.Add("A", starttime.AddMonths(i).ToString("MM", seCultureInfo) + "/" + starttime.AddMonths(i).ToString("yyyy", seCultureInfo));
mm = "1";
}
while (reader.Read())
{
var value = reader.GetDecimal(2);
// var column = new DataGridViewTextBoxColumn();
// column.HeaderText = header.ToString();
// this.dataGridView1.Columns.Add(column);
if (dataGridView1.RowCount < 2)
{
this.dataGridView1.Rows.Add();
}
this.dataGridView1.Rows[0].Cells[columnIndex].Value = value;
/* This --------------->*/ ee++;
columnIndex++;
}
Look at "ee". I want to keep value "ee" and bring it back in query command by new "ee".
Last date of value was wrong it's correct at 07/2015
If I got your question correctly , you want to reuse the SQL but increasing the 'ee' variable .
It is impossible .
If your business logic is about query based on different date, You have to build the SQL command again and again .
how to split into a string array and pass them to command parameters or hiddenfield, just need to split the string "S0010M,AZI002M,3,12/26/2013 12:00:00 AM,VDIQ20"
to pass with parameters like
cmd.Parameters.AddWithValue("#DealerCode", "S0010M");
cmd.Parameters.AddWithValue("#Code", "AZI002M");
cmd.Parameters.AddWithValue("#Qty", 33);
cmd.Parameters.AddWithValue("#ExpireDate", "12/26/2015");
cmd.Parameters.AddWithValue("#BatchNumber", "VDIQ20");
i have big problem about this .. please can you help me to fix this , beaus still learning the subject..
after click on Return button , take the data from gridview, it can be more than one rows.
protected void btnReturn_Click(object sender, EventArgs e)
{
int rowIndex = 0;
StringCollection SetDEL_Stores = new StringCollection();
if (ViewState["CurrentData"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
var DealerCode = HFDealerCode.Value;
var ItemIdentityCode = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[2].FindControl("ItemIdentityCode");
var Qty = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[8].FindControl("Quantity");
var ExpireDate = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[6].FindControl("ExpireDate");
var BatchNumber = (Label)GridViewSalesReturn.Rows[rowIndex].Cells[7].FindControl("BatchNumber");
CultureInfo ci = new CultureInfo("en-GB");
SetDEL_Stores.Add(DealerCode + "," + ItemIdentityCode.Text + "," + decimal.Parse(Qty.Text) + "," + DateTime.ParseExact(ExpireDate.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture) + "," + BatchNumber.Text);
rowIndex++;
}
InsertDEL_Stores(SetDEL_Stores);
}
}
}
//in InsertDEL_Stores(SetDEL_Stores); event , taking the stringline separated with "," ,,
private void InsertDEL_Stores(StringCollection SC_PurLinr)
{
String strConnString = ConfigurationManager.ConnectionStrings["CBConnectionString"].ConnectionString;
DataSet ds = new DataSet();
SqlConnection con = new SqlConnection(strConnString);
SqlCommand cmd = new SqlCommand("sp_DEL_Stores_IU", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DealerCode", SC_PurLinr[0]);
cmd.Parameters.AddWithValue("#Code", SC_PurLinr[1]);
cmd.Parameters.AddWithValue("#Qty", SC_PurLinr[2]);
cmd.Parameters.AddWithValue("#ExpireDate", SC_PurLinr[3]);
cmd.Parameters.AddWithValue("#BatchNumber", SC_PurLinr[4]);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
It is not clear why you need a string collection first. If you want to keep the contents of the single rows in the GridView then start defining a class for your items where every single field is typed correctly (string for strings, numeric for numerics and datetime for dates) Copying the content of the grid in a string collection is just a waste of time and memory because every time you need to use the values stored in the string collection you need to find the correct string and split it to the individual fields.
I could just offer a pseudocode here because I haven't the possibility to test it.
(As an example I have named this class MyItem, but you could call it as you wish)
public class MyItem
{
public string DealerCode;
public string ItemCode;
public int Quantity;
public Datetime ExpireDate;
public string BatchNumber;
}
Then in your loop
// To keep the content of the grid keyed on the BatchNumber field
Dictionary<string, MyItem> items = new Dictionary<string, MyItem>();
for (int rowIndex = 0; i < dtCurrentTable.Rows.Count; i++)
{
MyItem itm = new MyItem();
itm.DealerCode = HFDealerCode.Value.ToString();
itm.ItemCode = GetGridValue(rowIndex, 2, "ItemIdentityCode");
itm.Quantity = Convert.ToDecimal(GetGridValue(rowIndex, 8, "Quantity");
itm.ExpireDate = Convert.ToDateTime(GetGridValue(rowIndex, 6, "ExpireDate");
itm.BatchNumber = GetGridValue(rowIndex, 7, "BatchNumber");
// Add the item to the dictionary for future reuses, however if you just want to store
// the item in the database this line is not needed
items.Add(itm.BatchNumber, itm);
// notice that the storing is executed inside the loop that extracts the values
// so every row is updated/inserted in the database
InsertDEL_Stores(itm);
}
GetGridValue is a method that you should write taking the parameters passed and returning a string with the value searched on the current row of your gridview. This could be simple as
string GetGridValue(int rowIndex, int cellIndex, string controlName)
{
Control c = GridViewSalesReturn.Rows[rowIndex].Cells[cellIndex].FindControl(controlName);
return (c != null ? c.Value.ToString() : "");
}
but you need to test it for its correctness.
However, after that you have an istance of MyItem class that you could store in the dictionary for future reuses or just pass it to the database working procedure
private void InsertDEL_Stores(MyItem itm)
{
String strConnString = ConfigurationManager.ConnectionStrings["CBConnectionString"].ConnectionString;
using(SqlConnection con = new SqlConnection(strConnString))
using(SqlCommand cmd = new SqlCommand("sp_DEL_Stores_IU", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#DealerCode", itm.DealerCode);
cmd.Parameters.AddWithValue("#Code", itm.ItemCode);
cmd.Parameters.AddWithValue("#Qty", itm.Quantity);
cmd.Parameters.AddWithValue("#ExpireDate", itm.ExpireDate);
cmd.Parameters.AddWithValue("#BatchNumber", itm.BatchNumber);
con.Open();
cmd.ExecuteNonQuery();
}
}
I am aware that this code could raise more questions than the one that you try to resolve, neverless I think that this is more OOP than a simple string split
To split a string using commas as the separator character do the following
String[] values = str.split(",");
Then you can access the array in the following way
values[0];
But since your question is a bit confusing I suggest you read well the comments by other contributors what best suits your needs, how you are passing those values to the command parameters. Certainly, dictionaries and lists are more efficient than String collections
Hi I have a dropdown list and I want to update one item when I selecting it in dropdown list,I wrote this code but it only update the first item:
DBMethod db = new DBMethod();
DataTable dt = new DataTable();
string sqlcmd = "select * from dbo.Web_Personnel ";
dt = db.ReturnTableWithData(sqlcmd);
dt.Rows[0]["Job"] = txtjobE.Text;
dt.Rows[0]["ChildNo"] = txtchildnoe.Text;
dt.Rows[0]["Salary"] = txtsalary.Text;
db.UpdateDatatable(dt, "dbo.Web_Personnel");
yes this code by default will only update the first item because you are hard coding value 0 in it
dt.Rows[0]["Job"] = txtjobE.Text;
dt.Rows[0]["ChildNo"] = txtchildnoe.Text;
dt.Rows[0]["Salary"] = txtsalary.Text;
just declare a variable
int i = 0;
//change the value of I to desired value and less than dt.Rows.Count()
dt.Rows[i]["Job"] = txtjobE.Text;
dt.Rows[i]["ChildNo"] = txtchildnoe.Text;
dt.Rows[i]["Salary"] = txtsalary.Text;
Target a particular row using a variable i:
Identify the DB row to edit, eg:
int i = idOfUser // e.g. id = 3
dt.Rows[i]["Job"] = txtjobE.Text;
dt.Rows[i]["ChildNo"] = txtchildnoe.Text;
dt.Rows[i]["Salary"] = txtsalary.Text;