Qty Control in C# - c#

pstrjds, From the code you have provided I am trying to implement that code and the msdn link you provided couple of days ago. I am not sure how to put it together but I am see a message that "The variable name '#ID' has already been declared. Variable names must be unique within a query batch or stored procedurce." Do I need to create a stored procedurce? Can I assume I got the ID bit right as well, where you explained number of times? Thank you.
enter code here
cs.Open();
int remainingStock = 0;
string Query = "SELECT StockA SET QTY = #QTY " + "WHERE ID = #ID;";
SqlCommand cmd = new SqlCommand(Query, cs);
cmd.Parameters.Add("#ID", SqlDbType.Int);
cmd.Parameters["#ID"].Value = 1;
cmd.Parameters.AddWithValue("#ID", Query);
try
{
if (remainingStock == 1)
{
lbqty.Text = "Not enough stocks.";
}
else
{
cmd.CommandText = "UPDATE StockA SET QTY = QTY-1
WHERE ID=1";
int rowsUpdated = cmd.ExecuteNonQuery();
remainingStock--;
string remaining = "Remaining stocks: " +
remainingStock.ToString();
txQty.Text = remaining;
lbqty.Text = remaining;
DGA.Update(); //this is DataGridView
}
Int32 rowsAffected = cmd.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
cs.Close();
}

The problem is that you don't check for the case where ret == -1. Changing your second if-statement to if(ret < 1) should fix your issue.
Also, directly after the line cmd.ExecuteNonQuery(); add ret--; to sync the ret variable with the value that is now in the database.

I think this is your problem - you make ret - 1 while processing and then
txtQty.Text = "Remaining stocks: " + (ret - 1).ToString();
lbqty.Text = "Remaining stocks: " + (ret - 1).ToString();
that shows one less item. Try making it:
txtQty.Text = "Remaining stocks: " + ret.ToString();
lbqty.Text = "Remaining stocks: " + ret.ToString();

After reading your question again, I am more convinced that the comment I posted is actually the problem. You said in your question that your quantity is not going down. If you look at the return value from the line:
cmd.ExecuteNonQuery();
in your else statement I believe you will get a value of 0. This indicates that no records where updated. I believe the problem is exactly related to your query. If you connect to your database with a utility such as LINQPad or the Sql Management studio and run the query you have listed in your code I think you will find it is not updating anything. I highly suspect that your inventory is not being stored in a table called tblContacts. Which is why you can't select a quantity from it nor update a quantity in it.
Edit:
Meant to mention this initially and then got sidetracked and forgot to add it. I would put your SqlCommand in a using statement. The SqlCommand object is disposable and so it is good practice to place disposable objects in a using statement or in some sort of try/finally pattern where they can be cleaned up.
Additional edit - restructuring your code:
cs.Open();
int remainingStock = 0;
string Query = "SELECT QTY from tblInventory WHERE ID=19";
using(SqlCommand cmd = new SqlCommand(Query, cs))
{
var result = cmd.ExecuteScaler();
if (result != null)
{
string str = result.ToString();
if (!string.isNullOrWhiteSpace(str))
{
// NOTE: It would probably be safer to use int.TryParse here
remainingStock = Convert.ToInt32(cmd);
}
if (remainingStock == 0)
{
lbqty.Text = "Not enough stocks.";
}
else
{
cmd.CommandText = "UPDATE tblInventory SET QTY = QTY-1 WHERE ID=19";
int rowsUpdated = cmd.ExecuteNonQuery();
remainingStock--;
if (remainingStock == 1)
{
lbqty.Text = "Re-order. Remaining stocks: 1";
}
else
{
string remaining = "Remaining stocks: " + remainingCount.ToString();
txtQty.Text = remaining;
lbqty.Text = remaining;
}
}
}
else
lbqty.Text = "No stock for contact";
}
dgUpdate();
}
cs.Close();

Your application flow should be as following;
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection c = new SqlConnection("Data Source=.; Integrated Security=SSPI; Initial Catalog=FA");
SqlCommand cmd = new SqlCommand();
cmd.Connection = c;
c.Open();
// get remaining stocks
cmd.CommandText = "SELECT Qty from TEST WHERE Id=1";
int ret = Convert.ToInt32(cmd.ExecuteScalar().ToString());
if (ret == 0)
{
Label1.Text = "Not enough stocks.";
}
else
{
cmd.CommandText = "UPDATE TEST SET Qty = Qty-1 WHERE Id=1";
cmd.ExecuteNonQuery();
if (ret == 2)
{
Label1.Text = "Re-order. Remaining stocks: 1";
}
else
{
Label1.Text = "Remaining stocks: " + (ret-1).ToString();
}
}
c.Close();
}

The fist thing i can see is that this in not right
if (ret == 1)
{
lbqty.Text = "Re-order. Remaining stocks: 1";
dgUpdate();
}
else
should be
if (ret - 1 == 1)
{
lbqty.Text = "Re-order. Remaining stocks: 1";
dgUpdate();
}
else
because when the value you read is 1 and you decrease it its 0.

Related

How to check if user in mysql database exists (in c#)

So I know this is a often asked question but I want to check if the username is already taken in the database using c#. I tried this:
MySqlCommand cmd2 = new MySqlCommand("SELECT * FROM tablename WHERE(name = '" + tb1.Text + "');");
cmd2.Connection = connect;
connect.Open();
string unt = "";
try
{
MySqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
unt= dr.GetString("name");
}
dr.Close();
}
catch (Exception ex)
{
errorbox.Content = ex.Message;
}
finally
{
connect.Close();
}
if(unt == "" || unt == "0") {
continuel = false;
tb2.Text = "User " +tb1.Text+ " doesn't exist!";
Popup1.IsOpen = true;
}
Its a WPF project and the variable 'continuel' is set to true by default. The code doesn't recognize if a user doesn't exist.
First off your code is vulnerable to sql inject, you should never concatenate values into a query. secondly you can do a count and execute a scalar. Not I stripped down your code a little you'll have to add error handling back.
bool userExists = false;
private String sql = "SELECT COUNT(*) FROM tableName WHERE name = #usernameparam;";
MySqlCommand m = new MySqlCommand(sql);
m.Parameters.AddWithValue("#usernameparam", tb1.Text.Trim());
int userCount = Convert.ToInt32(m.ExecuteScalar());
if(userCount>0)
{
userExists = true;
}
//use userExists variable to evaluate if user exists

How can a test condition be based on the count from query result?

I want to create something like if (reader["assignID"].count > 2) then something happens. But I understand that MySqlDataReader does not have a count function. How else should I approach this?
I want to count the rows.
My code
try
{
string myConnectionString3;
myConnectionString3 = "server=localhost;uid=root;pwd=root;database=medicloud;SslMode=None;charset=utf8";
MySqlConnection connection3 = new MySqlConnection(myConnectionString3);
MySqlCommand cmd3 = new MySqlCommand();
EncodingProvider ppp3;
ppp3 = CodePagesEncodingProvider.Instance;
Encoding.RegisterProvider(ppp3);
cmd3.CommandType = CommandType.Text;
string sqlStr2 = "Select assignID from assign where userId=#name";
cmd3.Parameters.AddWithValue("#name", txtValue.Text);
cmd3.CommandText = sqlStr2;
cmd3.Connection = connection3;
connection3.Open();
MySqlDataReader reader1 = cmd3.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
if (reader1["assignID"].count > 2) //count rows if more than 2
{
txtAssignID1.Text += "Hello";
}
else
{
btnStart.IsEnabled = true;
string assignID = (reader1["assignID"].ToString());
txtAssignID1.Text += "Your exercise ID is: " + assignID;
}
}
}
else
{
txtAssignID1.Text += "You have not been assigned any exercise ID";
txtAssignID.IsEnabled = false;
}
connection3.Close();
}
catch (MySqlException)
{
}
If you want to know how many assignID for a single user are present then you should ask it to your database. Change your query to
string sqlStr2 = "Select COUNT(assignID) as Totals from assign where userId=#name";
then you use ExecuteScalar to get back the result
int assignCount = 0;
// We need to check for nulls, because if the where condition doesn't
// match any userid then ExecuteScalar returns null.
object result = cmd3.ExecuteScalar();
if(result != null)
assignCount = Convert.ToInt32(result);
And remove all the datareader stuff.
If you need to know also the value of AssignID then you should go back to the MySqlDataReader approach but with a different query again
string sqlStr2 = #"Select assignID, COUNT(assignID) as Totals
from assign where userId=#name
GROUP BY assignID";
.....
MySqlDataReader reader1 = cmd3.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
if ((int)reader1["Totals"] > 2)
{
// Not clear what you want to do if Totals > 2
txtAssignID1.Text += "Hello";
}
else
{
btnStart.IsEnabled = true;
string assignID = (reader1["assignID"].ToString());
txtAssignID1.Text += "Your exercise ID is: " + assignID;
}
}
}
else
{
txtAssignID1.Text += "You have not been assigned any exercise ID";
txtAssignID.IsEnabled = false;
}
If you only need to know if the count is > 2 it may be better to use a count query and execute a GetScalar. This way you only retrieve the data that is necessary.

Update query not throwing error

Thanks for the help in advance.
Im trying to use update query in C#
Error : command is getting executed even if I use incorrect values
Design view
Code :
protected void Button1_Click(object sender, EventArgs e)
{
try
{
con.Open();
cmd = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id='" + TxtEMPID.Text + "' and AvayaID ='" + TxtAvayaID.Text + "'", con);
cmd = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID ='" + TxtAvayaID.Text + "'", con);
cmd.ExecuteNonQuery();
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
con.Close();
}
catch (SqlException ex)
{
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
your code would look better like this, it not the most optimal, but ia already a way better piece of code then your snippet
1) added parameters using a helper function for the sql injection issue
2) an ExecuteNonQuery returns the rows affected, so if you are expecting that 1 row was updated, you can check on that
3) if you update a row with an id that not exists, it will not throw a SqlException like you are expecting in your code, this happens e.g. when locking occurs
public void Update()
{
var con = new SqlConnection();
try
{
var empId = TxtEMPID.Text
var avayaId = TxtAvayaID.Text
con.Open();
var cmd1 = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id=#empId and AvayaID = #avayaId", con);
cmd1.Parameters.Add(AddParameter("#empId",empId));
cmd1.Parameters.Add(AddParameter("#avayaId", avayaId));
var cmd2 = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID =avayaId", con);
cmd2.Parameters.Add(AddParameter("#avayaId", avayaId));
var rowsaffected1 = cmd1.ExecuteNonQuery();
var rowsAffected2 = cmd2.ExecuteNonQuery();
if (rowsaffected1 == 1 && rowsAffected2 == 1)
{
//success code goes here
//--------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
}
else
{
// failure code goes here
//-----------------------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
}
catch (SqlException ex)
{
//handle errors
}
finally
{
con.Close();
}
Console.ReadLine();
}
private SqlParameter AddParameter(string name, object value) {
var par = new SqlParameter();
par.ParameterName = name;
par.Value = value;
return par;
}
If you put "incorrect" values it just updates zero of records. No errors/exception expected here.

using one button to insert and update different db tables

I am using the same button "Save" to update a table called AnalysisExperiments and also to insert data into a table called "Analysis". however the update is not working. Here is the code:
#region Insert Data into Analysis Table
if (checkIfRepeatedJobNumber(tbJobNumber.Text.Trim()))
{
MessageBox.Show("Job Number is already exist.", "Repeated Data");
return;
}
string query = "insert into Analysis (ID, WellName, EstimatedStartDate, SOWComments, ProgressComments, Field, FocalPoint, StudyCompleted, Company, ReservoirPressure, ReservoirTemp, SelectedSamples) " +
"values (#ID, #WellName, #SamplingDate, #SOWComments, #ProgressComments, #Field, #FocalPoint, #StudyCompleted, #Company, #ReservoirPressure, #ReservoirTemp, #SelectedSamples)";
OleDbCommand cmd = new OleDbCommand(query, conn);
cmd.Parameters.AddWithValue("#ID", tbJobNumber.Text);
cmd.Parameters.AddWithValue("#WellName", tbWellName.Text);
cmd.Parameters.AddWithValue("#SamplingDate", dtpSamplingDate.Text);
cmd.Parameters.AddWithValue("#SOWComments", tbSOW_Comments.Text);
cmd.Parameters.AddWithValue("#ProgressComments", tbProgressComments.Text);
cmd.Parameters.AddWithValue("#Field", tbFieldName.Text);
cmd.Parameters.AddWithValue("#FocalPoint", tbFocalName.Text);
if (radYes.Checked)
cmd.Parameters.AddWithValue("#StudyCompleted", "Yes");
else
cmd.Parameters.AddWithValue("#StudyCompleted", "No");
cmd.Parameters.AddWithValue("#Company", tbCompany.Text);
cmd.Parameters.AddWithValue("#ReservoirPressure", tbReservoirPressure.Text);
cmd.Parameters.AddWithValue("#ReservoirTemp", tbReservoirTemp.Text);
cmd.Parameters.AddWithValue("##SelectedSamples", tbSelectedSamples.Text);
try
{
conn.Open();
int j = cmd.ExecuteNonQuery();
if (j == 1)
{
MessageBox.Show("Done");
this.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
#endregion
#region update analysis Exp but still no working
#region Update database
try
{ int k = 0;
OleDbDataAdapter da;
da = new OleDbDataAdapter("select* from [AnalysisExperiments]", conn);
string ExpQuery = "update AnalysisExperiments set SampleNumber = #SampleNumber, Status = #Status where ID = '" + tbJobNumber.Text + "' and Experiment = '";
foreach (DataGridViewRow row in dgvExperiments.Rows)
{
ExpQuery += row.Cells["Experiment"].Value.ToString() + "'";
OleDbCommand updateCommand = new OleDbCommand(ExpQuery, conn);
updateCommand.Parameters.Add("#SampleNumber", OleDbType.VarWChar);
MessageBox.Show(row.Cells["SampleNumber"].Value.ToString() + " | " + row.Cells["Status"].Value.ToString() + " | " + row.Cells["Experiment"].Value.ToString());
updateCommand.Parameters["#SampleNumber"].Value = row.Cells["SampleNumber"].Value.ToString();
updateCommand.Parameters.Add("#Status", OleDbType.Boolean);
updateCommand.Parameters["#Status"].Value = row.Cells["Status"].Value;
da.UpdateCommand = updateCommand;
conn.Open();
k = da.UpdateCommand.ExecuteNonQuery();
conn.Close();
}
if (k == 1)
MessageBox.Show("Done");
else
{
MessageBox.Show("Nothing Updated!");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
#endregion
#endregion
knowing that the compiler skips the loop in the update region.
At the second loop the query syntax becomes invalid cause the += that concatenates the previous text with the new one
Dim newQuery = ExQuery + row.Cells["Experiment"].Value.ToString() + "'";
And then use the new string for the ExecuteNonQuery.
Still this approach has many problems. You should separate this code in different methods and use parameters also for the last value
Have you tried to debug the foreach line to see if there are any rows in your dgvExperiments and if they are of type (or subtype of) DataGridViewRow ?

c#.net Error: There is already an open DataReader associated with this Command which must be closed first

Help, I am new to asp.net c#. I tried the codes once before but it didn't seems to have this error. So I can't seems to figure where do I make changes to.
Sever error :
There is already an open DataReader associated with this Command which must be closed first.
Codes:
string strConnectionString = ConfigurationManager.ConnectionStrings["FYPDB"].ConnectionString;
SqlConnection myConnect = new SqlConnection(strConnectionString);
string strCommandText = "select promoId FROM FYPDB.dbo.Promotions where membershipType LIKE '%' + #membership + '%' AND defaults LIKE '%' + #defaults + '%'";
try
{
string ddlmembership = ((DropDownList)dvInsertPromotion.FindControl("ddlAddMembershiplist")).SelectedItem.ToString();
string ddlDefault = ((RadioButtonList)dvInsertPromotion.FindControl("RadioButtonList2")).Text.ToString();
DataSet da = dal.retrieveMembership(ddlmembership, ddlDefault);
SiteGridView.DataSource = da;
SiteGridView.DataBind();
SqlCommand cmd = new SqlCommand(strCommandText, myConnect);
cmd.Parameters.Add("#membership", SqlDbType.NVarChar);
cmd.Parameters.Add("#defaults", SqlDbType.NVarChar);
cmd.Parameters["#membership"].Value = ddlmembership;
cmd.Parameters["#defaults"].Value = ddlDefault;
myConnect.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
//get number of count
//int count = da.Tables[0].Rows.Count;
int count = (int)cmd.ExecuteScalar();
if (count == 1)
{
defaultComfirm.Show();
promotion = false;
}
}
else
{
Label6.Text = "error didnt go through";
Label6.ForeColor = System.Drawing.Color.Gray;
Label6.Visible = true;
}
reader.Close();
}
finally
{
myConnect.Close();
}
you are using the same command object two times:
SqlDataReader reader = cmd.ExecuteReader();
int count = (int)cmd.ExecuteScalar();
This is not possible.
It is not necessary to use a reader if you just want to have the count of rows. In this case you can use the ExecuteScalar.
Like this:
string strCommandText = "select COUNT(promoId) FROM FYPDB.dbo.Promotions where membershipType LIKE '%' + #membership + '%' AND defaults LIKE '%' + #defaults + '%'";
try
{
...
int count = (int)cmd.ExecuteScalar();
...
Regards
Oliver
Looking at your code, you just need count of rows matching the criteria.
So if you just need rows count you could use any of these options.
Option 1:
Find out count by reading all rows
int count =0;
while(reader.Read()) count++;
if (count == 1)
{
defaultComfirm.Show();
promotion = false;
}
else
{
...
}
reader.Close();
Option 2:
My preferred choice for this case, Modify your query to return the count (SELECT COUNT(*)).
string strCommandText = "select count(promoId) FROM FYPDB.dbo.Promotions where membershipType LIKE '%' + #membership + '%' AND defaults LIKE '%' + #defaults + '%'";
now,
int count = (int)cmd.ExecuteScalar();
if (count == 1)
{
defaultComfirm.Show();
promotion = false;
}
else
{
...
}
reader.Close();
Option 3:
Other option to convert it to DataTable and get the row count.
using (DataTable dt = new DataTable())
{
dt.Load(reader);
if (dt.Rows.Count == 1)
{
defaultComfirm.Show();
promotion = false;
}
else
{
...
}
reader.Close();
}
try to execute cmd.ExecuteScalar() before cmd.ExecuteReader().
int count = (int)cmd.ExecuteScalar();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
//get number of count
//int count = da.Tables[0].Rows.Count;
if (count == 1)
{
defaultComfirm.Show();
promotion = false;
}
}

Categories

Resources