I am trying to delete the items within the listbox, which already exists in my database. My listbox is populated by a set of random names, and the ones that are equal to the data from the table rows should be deleted.
My code:
SqlCommand RemoveUserName = new SqlCommand("SELECT * FROM Name WHERE ([Name] = #check)", Con);
RemoveUserName.Parameters.AddWithValue("#check", listbox1.Items);
SqlDataReader dr = RemoveUserName.ExecuteReader();
if (dr.HasRows)
{
listBox1.Items.Remove(); // ?? Remove the names which are already in the database
}
else
{
// remain in listbox
}
Getting an error in my parameter value and I don't know how to delete the said items.
EDITED my current code:
SqlCommand RemoveUserName = new SqlCommand("SELECT * FROM Name", Con);
SqlDataReader dr = RemoveUserName.ExecuteReader();
while (!dr.Read())
{
for (int i = 0; i < listBox1.Items.Count; ++i)
{
if (listBox1.Items[i].ToString() == dr["Name"].ToString())
listBox1.Items.Remove(listBox1.Items[i]);
}
}
Has no error anymore, but is still not functional.
WORKING CODE:
for (int i = listBox1.Items.Count - 1; i >= 0; --i)
{
using (var cmd = new SqlCommand("UPDATE [Name] SET [Name] = Name WHERE [Name] = #name", Con))
{
cmd.Parameters.AddWithValue("#name", listBox1.Items[i].ToString());
if (cmd.ExecuteNonQuery() > 0)
{
listBox1.Items.RemoveAt(i);
}
}
}
Thanks # LarsTech
It helps to loop backwards through the list in order to avoid indexing issues:
for (int i = listBox1.Items.Count - 1; i >= 0; --i) {
using (var cmd = new SqlCommand("DELETE FROM [Name] WHERE [Name] = #name", Con)) {
cmd.Parameters.AddWithValue("#name", listBox1.Items[i].ToString());
if (cmd.ExecuteNonQuery() > 0) {
listBox1.Items.RemoveAt(i);
}
}
}
ExecuteNonQuery will return the number of records affected, so if it's greater than zero, the name was found and deleted.
Make sure to close your connection object, too. Best by putting it also in a using block the way the SqlCommand object is in my example.
Your table and column names need to be improved.
As I understood,
1) You need to delete items from listbox that already exists in your database and read by SqlDataReader.
You first need to loop into reader. So instead of !while(reader.Read()) use while(reader.Read())
2) Now you want to remove actual item from listbox, if it exists in reader.
So try to do following to remove item from listbox inside reader while loop
for (int n = listBox.Items.Count - 1; n >= 0; --n)
{
var removelistitem = dr["Name"].ToString();
if (listBox.Items[n].ToString().Contains(removelistitem))
{
listBox.Items.RemoveAt(n);
}
}
Now after while loop execution. your listbox will only have items not present in your reader (data from database).
Hope this helps.
Edit
Its ok to loop in listbox items.
Use RemoveAt instead. (See above answer)
try this:
while (!dr.Read())
{
for (int i=0; i<listBox1.Items.Count; ++i)
{
if (listBox1.Items[i].ToString() == dr["columnName"].ToString())
listBox1.Items.Remove(listBox1.Items[i]);
}
}
SqlReader must be read before use it. If there's no rows in the Reader, code in while block won't be executed.
EDIT I got a problem making you unhappy....
The code you provided:
RemoveUserName.Parameters.AddWithValue("#check", listbox1.Items);
Is wrong, because #check parameter expects string, but you provided was ObjectCollection. Revise query "SELECT * FROM Name WHERE ([Name] = #check)" to "SELECT * FROM Name". and remove the line AddWithValue.
Related
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,
Hi i am new here i just want to ask question for this code.
i am making a condition on my new buttom that generate Enumber= Employee Number.
i have database but no data record yet. if i press my new buttom my sql statement will select he last record on my data but i don't have yet data so i am trying to make a condition.
if Enumber is empty in database it should return and give the new Enumber on my textbox = txtEnumber.Text = "100000".
i hope you understand my problem.
con.Open();
cmd = new SqlCommand("SELECT TOP 1 Enumber FROM Employee ORDER BY Enumber DESC ", con);
dr = cmd.ExecuteReader();
dr.Read();
if (dr["Enumber"] == null) // Error: "Invalid attempt to read when no data is present."
{
txtEnumber.Text = "100000";
return;
}
else
{
String a = dr["Enumber"].ToString();
txtEnumber.Text = ("");
for (int i = 0; i < 1; i++)
{
string val = a.Substring(1, a.Length - 1);
int newnumber = Convert.ToInt32(val) + 1;
a = newnumber.ToString("100000");
}
txtEnumber.Text = a;
}
con.Close();
Since you don't have any row in your case, you can't iterate your reader. Instead of that, you can use ExecuteScalar which returns null as an object if there is no data in first column of the first row since your query returns as SELECT TOP 1...
var result = cmd.ExecuteScalar();
if(result == null)
{
txtEnumber.Text = "100000";
}
You should check whether there are rows first. dr.Read() returns whether the DataReader has rows, use it.
Your DataReader returns no results...
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
// read data for first record here
}
If you have more than one result, use a 'while' loop.
while (dr.Read()) {
// read data for each record here
}
You should use dr.HasRows to check whether there is data or not.
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
dataTable.Load(dr);
}
If you have more than one result, use a 'foreach' loop.
foreach (DataRow Drow in datatable.Rows)
{
// read data for each record here
}
Try This is Worked..
I am new in WPF. I am trying to load the values from database to fill in CheckedListBox. Based on a condition, some items must be set to checked while loading in checkedlistbox.
How to do this? I have tried the code below, items are loaded in CheckedListBox, but are not checked.
Below is values loaded to checked listbox
public void fillcheck()
{
con = new SqlConnection(connectionstring);
con.Open();
string comboquery = "SELECT [Machine] FROM Department Where active='True'";
SqlCommand cmd = new SqlCommand(comboquery, con);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string fil1 = rdr.GetString(0);
Checkedlistbox1.Items.Add(fil1);
}
rdr.Close();
}
int departmentID=60//for just refer
Object[] jobs = CheckedlistBox1.Items.Cast<Object>().ToArray();
foreach (Object obj in jobs)
{
string query = "SELECT [Machine] FROM Department Where ID='" + departmentID+ "'";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
string mac = rdr.GetString(0);//Here i get two values(XRAY,CT)but finally shown CT only be checked,so how to do both checked
if (mac == obj.ToString())
{
int indexx = CheckedlistBox1.Items.IndexOf(mac);
if (indexx >= 0)
{
CheckedlistBox1.SetItemChecked(indexx, true);
}
}
}
rdr.Close();
}
You need to transfer your SqlDataReader rdr content to a DataTable. That will help you get a DataTable object containing multiple rows like you have mentioned.
Now for the next step, you can apply a foreach on that DataTable object to iterate over all its rows like this :
foreach(DataRow dr in dt.Rows)
{
if(yourCondition)
{
//set isChecked = true for the checkbox.
}
}
UPDATE :
Try modifying your while loop like this :
while (rdr.Read())
{
string mac = rdr.GetString(0);
ListItem li = new ListItem();
li.Value = "yourBindedValue";// some value from database column
li.Text = "yourBindedText";// use mac if its text.
int index = Checkedlistbox1.Items.IndexOf(li);
if (index >= 0)
{
Checkedlistbox1.SetItemChecked(index, true);
}
}
I have tested this and it works. You just have to pass the Text and Value of the CheckBoxListItem that you are trying to find in the li object and you can get the index if it exists. Make sure you pass both the attributes.
You should have used code-
foreach (int indexChecked in chlstBox.Items)
instead of
foreach (int indexChecked in chlstBox.CheckedIndices)
At start you have 0 selected items and thats why your outer for loop is not working..
EDIT-
Basic Logic is also incorrect.
You should loop through dataset, find the string in checkboxlist and then check it. So, outer foreach loop is not required. Also, make sure that you are using correct checkboxlist variable. In for loop you are using chlstBox
and while searching you are using Checkedlistbox1 ....
Im wondering how to make my checkboxes in column[3]in dtg_ksluzby checked when the value is in the DB.
klisluz(table where I get the data from) contains columns, id, subkey(which is = vyberradek), text, pocet
This is code for inserting into db.
foreach (DataGridViewRow row in dtg_ksluzby.Rows)
{
if (Convert.ToBoolean(row.Cells[3].Value) == true)
{
SqlCommand prikaz2 = new SqlCommand("INSERT INTO klisluz(text,pocet,akce,subkey) values(#val1,#val2,#val3,#val4) ", spojeni);
prikaz2.Parameters.AddWithValue("#val1", row.Cells["text"].Value);
prikaz2.Parameters.AddWithValue("#val2", row.Cells["pocet"].Value);
prikaz2.Parameters.AddWithValue("#val3", row.Cells["akce"].Value);
prikaz2.Parameters.AddWithValue("#val4", max + 1);
spojeni.Open();
prikaz2.ExecuteNonQuery();
spojeni.Close();
}
}
Now I would like to check the checkbox when the item is inserted in DB.
Would someone propose me a clue please?
I think I can algorithm this isssue, but I have no idea how can I turn it into the code I thought I can do it somehoe like this :
SqlCommand novyprikaz3 = new SqlCommand("SELECT * FROM klient WHERE ID_K=" + vyberradek, spojeni); //vyberradek selects row ID
spojeni.Open();
SqlDataReader precti = novyprikaz.ExecuteReader();
if (precti.Read())
{
If text in (row where ID_K=number which comes from vyberradek) is in dtg_ksluzby then check the checkbox in the same row
}
I would like to use this for USER to know which columns did he selected before when he is editing
Thank so much in advance.
for (int i = 0; i < dtg_ksluzby.Rows.Count; i++)
{
var row = dtg_ksluzby.Rows[i];
using(var novyprikaz2 = new SqlCommand("SELECT * FROM klient WHERE ID_K=" + vyberradek, spojeni))
{
spojeni.Open();
SqlDataReader precti2 = novyprikaz2.ExecuteReader();
if (precti2.HasRows)
{
row.Cells[3].Value = true;
}
}
}
You have to change vyberradek accordingly to row content.
Try to count it and use ExecuteScalar as below
SqlCommand novyprikaz3 = new SqlCommand("SELECT count(1) FROM klient WHERE ID_K=" + vyberradek, spojeni); //vyberradek selects row ID
spojeni.Open();
Int32 cnt = (Int32) novyprikaz.ExecuteScalar();
If cnt is more than 0 the items exists.
I am trying to see if an ID exists in a database in this case it's vetID.
To see if the result of the SQL query is successfull I am trying to use rdata.FieldCount
FieldCount always seems to return 11 even if the input ID (variable i) is = -400 (an id number that cannot exist in the database). I have also tried with other numbers that are not possible such as 100 or 800 (the database has only 1 - 5 items in it)
var mySQLCommand = new SqlCeCommand("SELECT * FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
if (rdata.FieldCount >= 1)
{
MessageBox.Show(" HAS ROWS "); go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}
MessageBox.Show("rdata FieldCount " + rdata.FieldCount + " i has value " + i);
Is there a more elegant way to check an ID is still valid in the database and has not been deleted?
OK.. before you call me Stupid ... im guessing the FieldCount is just the exactly that the FieldCount and not the FieldCount of the returned Query ... doh...
But the question still stands is there an elegant way to know if the ID is still there in the database?
FieldCount always returns 11 because (I assume) there are 11 columns in the table.
A better way is:
var sql = new SqlCeCommand("select top 1 vetid from vets where vetid = #id", dbCon);
sql.Paramaters.AddWithValue("id", i);
if (null != mySqlCommand.ExecuteScalar())
{
// ID exists
}
If you are using a datareader you can't get a rowcount using fieldcount. But if you wanted to leave the query the same you'd do:
var mySQLCommand = new SqlCeCommand("SELECT * FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
if (rdata.read() )
{
MessageBox.Show(" HAS ROWS ");
go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}
MessageBox.Show("rdata FieldCount " + rdata.FieldCount + " i has value " + i);
Another way to check is to use a select count(*) to see if it's in the table and that would be 0 if it doesn't exist.
var mySQLCommand = new SqlCeCommand("SELECT count(*) FROM vets WHERE vetID = #ID", dbCon);
mySQLCommand.Parameters.AddWithValue("ID", i);
SqlCeDataReader rdata = mySQLCommand.ExecuteReader();
int rowCount = 0;
if ( rdata.read() ) {
rowCount = rdata[0];
}
An sql reader is a forward reader only - so you cannot get the number of rows form a property. FieldCount is the number of columns in the current record. The only way to the get the number of rows returned is to read them all in or to run a count query before hand (which might not be concurrency safe)
Try using the HasRows property instead:
if (rdata.HasRows)
{
MessageBox.Show(" HAS ROWS "); go = true;
}
else
{
MessageBox.Show("NO ROWS RETURNED");
}