I am using C# to create a windows form.
I am trying to set a condition statement for a particular value that is retrieved from my database by the onclick of a button. The datatype of the column is 'integer'.
Below is my code:
string checkquantity = "SELECT `inventory_item`.`Item_Quantity_Available`FROM `inventory_item` , `patient`, `out_treatment`WHERE `inventory_item`.`Item_ID` = `out_treatment`.`Inventory_ID`AND `patient`.`Patient_ID` = `out_treatment`.`Patient_ID`AND `out_treatment`.`Patient_ID`= '" + pid + "' ";
MySqlCommand selectout = new MySqlCommand(checkquantity, connect);
MySqlDataAdapter selectdata = new MySqlDataAdapter(checkquantity, connect);
DataTable selecttable = new DataTable();
selectdata.Fill(selecttable);
DataSet ds = new DataSet();
selectdata.Fill(selecttable);
selectdata.Fill(ds);
int i = ds.Tables[0].Rows.Count;
if ( i <= 0)
{
MessageBox.Show("Out of Stock");
}
I'm new with c#.
I don't think the int i = ds.Tables[0].Rows.Count; is the right way.
Any help is much appreciated.
First of all, like #Flydog57 said, you should not concatenate your sql query. The best way is to use parameters, for example:
string checkquantity = "SELECT i.Item_Quantity_Available " +
" FROM inventory_item i JOIN out_treatment t ON i.Item_Id = t.Inventory_ID " +
" JOIN patient p ON t.Patient_ID = p.PatiendID " +
" WHERE t.Patient_ID = #Patiend_ID";
MySqlCommand selectout = new MySqlCommand(checkquantity, connect);
// set the parameter value
selectout.Parameters.AddWithValue("#Patiend_ID", patient_id_value);
MySqlDataReader rdr = cmd.ExecuteReader();
if (rdr.Read())
{
if ((int)rdr["Item_Quantity_Available"] == 0)
MessageBox.Show("Out of Stock");
}
In second place, you could use a MySqlDataReader to verify that Item_Quantity_Available is equal to 0, like in the previous example. Otherwise, If you just wants to verify if there is data, the condition could be something like that:
if (!rdr.Read())
{
MessageBox.Show("Out of Stock");
}
The third improvemente is to join tables with the join clause.
Related
i would like to create an id generator based on their department selected from the dropdownlist. lets say my ddl has 3 departments (A,B,C) and when generating an id it will be A20181001 and then A20181002 upon submission but when i pick B from the ddl after sending A20181001 to the database, it will be B20181001.
so far i have created the code for the increment for the id without the departments. here is the code i did so far. (I used the date for today so the 20181001 is just an example):
void getMRF_No()
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
int mrf = 0;
int i;
string a;
//string x = Request.QueryString["BUnit"];
string mrfNo = "";
database db = new database();
string conn = dbe.BU();
SqlConnection connUser = new SqlConnection(conn);
SqlCommand cmd = connUser.CreateCommand();
SqlDataReader sdr = null;
string query = "SELECT TOP 1 MRF_NO FROM incMRF ORDER BY MRF_NO DESC";
connUser.Open();
cmd.CommandText = query;
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr.GetInt32(0).ToString();
}
if (mrfNo == "")
{
mrfNo = Convert.ToString(year) + "" + 00;
}
mrf += 0;
i = Convert.ToInt32(mrfNo) + 1;
a = i.ToString();
txtMRFNo.Text = a;
connUser.Close();
}
any help to improve this code will be helpful. thank you :)
EDIT:
here is the dropdown list code:
void SelectBU()
{
string database = dbe.BU ();
using (SqlConnection con = new SqlConnection(database))
{
con.Open();
string query = "select BUnit from BusinessUnit";
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
DataSet ds = new DataSet();
sda.Fill(ds, "BUnit");
ddlBu.DataSource = ds;
ddlBu.DataTextField = "BUnit";
ddlBu.DataValueField = "BUnit";
ddlBu.DataBind();
selectOption(ddlBu, "Select Dept");
}
con.Close();
}
}
EDIT2: I will state what im searching for here incase some doesnt know or understand. What i want is upon selecting a department from a dropdownlist, for example i picked A. the textbox show show A2018102201. if i select B it should show B2018102201 and if its C then c2018102201. and it will change its number once i submit it to a database and a new form loads. So if A2018102201 is already in the database, then the text shown in the text box will be A2018102202. BUT if i select B then the textbox will show B2018102201 since it does not exist in the database yet.
First you should get max ID, then increase the numeric part of your Id, and If this is a multi-user application, you have to lock your table, because it might create many ID duplication, Therefore I'm not recommend to create ID like this on c#, it is better to create a Sequence on SQL server. but I wrote this sample for you, just call it with proper value.
static string getMRF_No(string prefixCharFromDropDownList)
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
string mrfNo = "";
SqlConnection connUser = new SqlConnection("Server=130.185.76.162;Database=StackOverflow;UID=sa;PWD=$1#mssqlICW;connect timeout=10000");
SqlCommand cmd = new SqlCommand(
$"SELECT MAX(MRF_NO) as MaxID FROM incMRF where MRF_NO like '{prefixCharFromDropDownList}%'"
,connUser
);
connUser.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr["MaxID"].ToString();
}
if (mrfNo == "")
{
mrfNo = prefixCharFromDropDownList + year + "000";
}
else
{
mrfNo = prefixCharFromDropDownList + (long.Parse(mrfNo.Substring(1)) + 1).ToString().PadLeft(2);
}
sdr.Close();
cmd = new SqlCommand($"INSERT INTO incMRF (MRF_NO) values ('{mrfNo}')",connUser);
cmd.ExecuteNonQuery();
connUser.Close();
//txtMRFNo.Text = prefixCharFromDropDownList + i.ToString();
return mrfNo;
}
I call this method on a console application as test.
static void Main(string[] args)
{
// send dropdown (selected char) as prefix to method
var newAId = getMRF_No("A");
var newAnotherAId = getMRF_No("A");
var newBId = getMRF_No("B");
var newAnotherAId2 = getMRF_No("A");
Console.ReadKey();
}
I am trying to get a sum with a column from a ms access database but so not nothing has worked this is what I have
Conn.Open();
Command.CommandText = "Select SUM(c_qty) from COLLVAULT_COINS WHERE c_type!='US Currency' AND c_type!='World Currency' AND c_type!='World Coins' AND c_listName = '" + activeCollection + "'";
int total_1 = Convert.ToInt32(Command.ExecuteScalar());
//total sum - get how many match the query
lblcollectedcount.Text = Convert.ToString(total_1);
Conn.Close();
any help would be nice.
Conn.Open();
Command.CommandText = "Select SUM(c_qty) from COLLVAULT_COINS WHERE c_type <>'US Currency' AND c_type<>'World Currency' AND c_type<>'World Coins' AND c_listName = '" + activeCollection + "'";
int total_1 = Convert.ToInt32(Command.ExecuteScalar());
//total records
lblcollectedcount.Text = Convert.ToString(total_1);
Conn.Close();
I had to use <> as not equals to instead of !=
You could try something like this, assuming you want the number of records that were matched with your query:
Conn.Open();
Command.CommandText = "Select SUM(c_qty) as sum, Count(*) as count from COLLVAULT_COINS WHERE c_type <> 'US Currency' AND c_type <> 'World Currency' AND c_type <> 'World Coins' AND c_listName = '" + activeCollection + "'"; //
int total_matches = 0;
using (MySqlDataReader dataReader = Command.ExecuteReader())
{
if (dataReader.Read())
{
lblcollectedcount.Text = Convert.ToString(dataReader["sum"]);
total_matches = Convert.ToInt32(dataReader["count"]);
}
else
{
//nothing was read, handle that case
}
}
Conn.Close();
EDIT:
Misunderstood what the OP was asking for, and I also didn't catch the '<>' error.
I'll still keep this answer here, just for reference code.
This is my second question here in StackOverflow and this is where im stuck
i want to loop every value in a multiline textbox and pass it as query criteria then fill my DataGridView with the result (multiple results).
The problem is. that i cannot pass more than 1 value from the textbox. i can execute correctly the query but its not looping correctly as it only shows the result of the first value in my data grid and i want the data(result) from every line in the textbox
my code is
for (int i = 0; i < textBox1.Lines.Length; i++)
{
Connect();
OracleCommand cmd = new OracleCommand();
OracleDataAdapter adapter = new OracleDataAdapter();
DataTable dt = new DataTable();
cmd = new OracleCommand(OraSql + OraSql2 + orasql3 + OraSql4, con);
adapter = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();
adapter.Fill(dt);
foreach (DataRow row in dt.Rows)
{
dataGridView1.Rows.Add
(
row[0].ToString(),
row[1].ToString(),
row[2].ToString(),
row[3].ToString(),
row[4].ToString(),
row[5].ToString()
);
}
}
i hope that i explained myself correctly here
Thank you!
this is my query
string OraSql = #"SELECT r.ixkitl ""Parent Part Number"",
r.ixlitm ""Component Part Number"",
i.imdsc1 ""Description"",
SUM((r.ixqnty/10000)) ""Qty per Harness"",
To_date(r.ixefff+1900000, 'YYYYDDD') ""Effective From Date"",
To_date(r.ixefft+1900000, 'YYYYDDD') ""Effective Thru Date"",
r.ixtbm ""Bill Type"",
r.ixmmcu ""Branch Plt""
FROM proddta.f3002 r,
proddta.f4101 i";
string OraSql2 = #"
WHERE (i.imlitm IN '" + textBoxX1.Text.ToString() + "'AND i.imitm = r.ixkit)";
string orasql3 = #"
AND (r.ixmmcu = ' 3320' AND r.ixtbm = 'M ')";
string OraSql4 = #"
AND r.ixefff <= (to_char(SYSDATE, 'YYYYDDD')-1900000)
AND r.ixefft >= (to_char(SYSDATE, 'YYYYDDD')-1900000)
GROUP BY r.ixkitl,
r.ixlitm,
r.ixqnty,
r.ixtbm,
r.ixmmcu,
r.ixefff,
r.ixefft,
i.imdsc1
ORDER BY r.ixkitl,
r.ixlitm";
Im new to c# here. I have a comboBox codes that enable user to choose month and dates. When user click cmdSend button, the program will retrieve the month & date form comboBox and call dbConnect.Select class function to do the select mysql statement.
private void cmdSend_Click(object sender, System.EventArgs e)
{
List<string>[] list;
list = dbConnect.Select(month_list.Text, year_list.Text);
printer_info.Rows.Clear();
for (int i = 0; i < list[0].Count; i++)
{
int number = printer_info.Rows.Add();
printer_info.Rows[number].Cells[0].Value = list[0][i];
printer_info.Rows[number].Cells[1].Value = list[1][i];
printer_info.Rows[number].Cells[2].Value = list[2][i];
printer_info.Rows[number].Cells[3].Value = list[3][i];
}
}
the retrieve database class:
public List<string>[] Select(string month,string year)
{
string query = "SELECT * FROM page_counter where month ='" + month + "' AND year ='" + year + "' ;";
//Create a list to store the result
List<string>[] list = new List<string>[4];
list[0] = new List<string>();
list[1] = new List<string>();
list[2] = new List<string>();
list[3] = new List<string>();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"].ToString() + "");
list[1].Add(dataReader["month"].ToString() + "");
list[2].Add(dataReader["year"].ToString() + "");
list[3].Add(dataReader["page_count"].ToString() + "");
}
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return list to be displayed
return list;
}
else
{
return list;
}
}
However this code does not work, can someone advise me please?
EDITED:
string query = "SELECT * FROM page_counter where month = #month AND year = #year;";
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("#month",month);
cmd.Parameters.AddWithValue("#year",year );
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"].ToString() + "");
list[1].Add(dataReader["month"].ToString() + "");
list[2].Add(dataReader["year"].ToString() + "");
list[3].Add(dataReader["page_count"].ToString() + "");
}
//close Data Reader
dataReader.Close();
I have edited the code as suggested,However I have an error on the AddWithValue, it say : does not contain a definition for AddWithValue and no extension method AddWithValue, I have added the Data.MySqlClient reference but still remain the same. Please advise.
Problem 1 : You need to use SelectedItem property of the combobox to get the selected item from it.
Solution 1:
Replace This:
list = dbConnect.Select(month_list.Text, year_list.Text);
With This:
list = dbConnect.Select(month_list.SelectedItem.ToString(),
year_list.SelectedItem.ToString());
Problem 2:
i beilve that your Month and Year columns in your Database are INT columns.if they are INT columns you dont need to enclose the month and year parameter values within single quotes.
Solution 2:
Try This:
string query = "SELECT * FROM page_counter where month =
" + month + " AND year =" + year + " ;";
Suggestion : Your query is open to sql injection attacks i'd suggest to use Parameterised queries to avoid them.
Try This with Parameterised queries:
string query = "SELECT * FROM page_counter where month = #month AND year = #year;";
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("#month",month);
cmd.Parameters.AddWithValue("#year",year );
//Remaining same
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"].ToString() + "");
list[1].Add(dataReader["month"].ToString() + "");
list[2].Add(dataReader["year"].ToString() + "");
list[3].Add(dataReader["page_count"].ToString() + "");
}
//close Data Reader
dataReader.Close();
Code below is taking hours of time to execute. I'm comparing each string from database to calculate N00,N01,N10,N11 parameters. Temp1 is List of type string it consists of more than 5000 words
foreach (string ri in temp1)
{
for (int a3 = 0; a3 < ssl.Count; a3++)
{
//for (int tn = 0; tn < tempNam.Count ; tn++)
//{
try
{
SqlCommand cmd5 = new SqlCommand("select count(*) from sample s inner join sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + "=0 and s.KeyWord='y' and s. " + ssl[a3].ToString()+ "=0", con);
int im = (int)cmd5.ExecuteScalar();
if (im == 1)
{
gh += 1;
}
SqlCommand cmd6 = new SqlCommand("select count(*) from sample s inner join sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + "=0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + ">0", con);
int im1 = (int)cmd6.ExecuteScalar();
if (im1 == 1)
{
gh2 += 1;
}
SqlCommand cmd7 = new SqlCommand("select count(*) from sample s inner join sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + ">0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + "=0", con);
int im2 = (int)cmd7.ExecuteScalar();
if (im2 == 1)
{
gh3 += 1;
}
SqlCommand cmd8 = new SqlCommand("select count(*) from sample s inner join sample ss on ss.KeyWord='" + ri + "' and ss. " + ssl[a3].ToString() + ">0 and s.KeyWord='y' and s. " + ssl[a3].ToString() + ">0", con);
int im3 = (int)cmd8.ExecuteScalar();
if (im3 == 1)
{
gh4 += 1;
}
if (a3 == (ssl.Count-1))
{
SqlCommand ins = new SqlCommand("update sample set N00=" + gh + " where KeyWord='" + ri + "'", con);
ins.ExecuteNonQuery();
gh = 0;
SqlCommand ins1 = new SqlCommand("update sample set N01=" + gh2 + " where KeyWord='" + ri + "'", con);
ins1.ExecuteNonQuery();
gh2 = 0;
SqlCommand ins2 = new SqlCommand("update sample set N10=" + gh3 + " where KeyWord='" + ri + "'", con);
ins2.ExecuteNonQuery();
gh3 = 0;
SqlCommand ins4 = new SqlCommand("update sample set N11=" + gh4 + " where KeyWord='" + ri + "'", con);
ins4.ExecuteNonQuery();
gh4 = 0;
}
}
catch (Exception ex)
{
}
// }
}
}
SqlCommand cmd1s = new SqlCommand("select KeyWord from sample", con);
SqlDataAdapter da = new SqlDataAdapter(cmd1s);
DataSet ds = new DataSet();
da.Fill(ds, "sample");
foreach (DataRow dr in ds.Tables[0].Rows)
{
string dd = dr["KeyWord"].ToString();
if (dd != "y")
{
if (!li.Contains(dd))
{
li.Add(dd);
}
}
}
Put an index on Sample.KeyWord. This would make this a hell of a lot faster.
As with Anthony's comment below, there's a lot wrong with this code. The index is what I'm guessing is taking the most time, but you should read these topics as well:
Evil Practices - Swallowing Exceptions
The SqlParameter Class
The using() construct - This applies to any object implementing the IDisposable interface.
.NET Naming Conventions and Programming Standards - Best Practice - It is crucial to have meaningful names at the very least.
Look here for creating indices: http://msdn.microsoft.com/en-us/library/ms188783.aspx
Sorry, but your code is very hard to understand with the variables named the way they are.
I refactored your query for readability, moved to reusing a single SqlCommand (two in total if you count the one outside of the loop) and removed the extra queries.
I'm guessing the poor performance is tied to lack of object reuse, replication of effort with your queries, and you're probably throwing exceptions left and right and the try/catch is causing the stack to unwind every time you throw an exception! Check the output pane for debug information or set a breakpoint on the line System.Diagnostics.Debug.Print(ex.ToString());. Unwinding the stack will kill execution time.
I'm not sure if you're using poor variable names, or if you obfuscated your code, but you should really thing about putting meaningful variable names in code you need help with.
I'm positive that there is alot more you can do to optimize your code, but I'd take care of reusing the SqlCommand, removing repeated queries, and correctly handling your exception handling first.
foreach (string ri in temp1)
{
for (int index = 0; index < ssl.Count; index++)
{
try
{
SqlCommand command;
string query;
query = string.Format("select count(*) from sample s inner join sample ss on ss.KeyWord='{0}' and ss.{1}=0 and s.KeyWord='y' and s.{1}=0", ri, ssl[index].ToString());
command = new SqlCommand(query, con);
if ((int)command.ExecuteScalar() == 1)
{
gh++;
gh3++;
}
query = string.Format("select count(*) from sample s inner join sample ss on ss.KeyWord='{0}' and ss.{1}=0 and s.KeyWord='y' and s.{1}>0", ri, ssl[index].ToString());
command = new SqlCommand(query, con);
if ((int)command.ExecuteScalar() == 1)
{
gh2++;
gh4++;
}
if (index == (ssl.Count-1))
{
query = string.Format("update sample set N00={0} where KeyWord='{1}'", gh.ToString(), ri);
command = new SqlCommand(query, con);
command.ExecuteNonQuery();
gh = 0;
query = string.Format("update sample set N01={0} where KeyWord='{1}'", gh2.ToString(), ri);
command = new SqlCommand(query, con);
command.ExecuteNonQuery();
gh2 = 0;
query = string.Format("update sample set N10={0} where KeyWord='{1}'", gh3.ToString(), ri);
command = new SqlCommand(query, con);
command.ExecuteNonQuery();
gh3 = 0;
query = string.Format("update sample set N11={0} where KeyWord='{1}'", gh4.ToString(), ri);
command = new SqlCommand(query, con);
command.ExecuteNonQuery();
gh4 = 0;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.ToString());
}
}
}
SqlCommand command = new SqlCommand("select KeyWord from sample", con);
SqlDataAdapter da = new SqlDataAdapter(command);
DataSet ds = new DataSet();
da.Fill(ds, "sample");
foreach (DataRow dr in ds.Tables[0].Rows)
{
string KeywordCell = dr["KeyWord"].ToString();
if (KeywordCell != "y")
{
if (!li.Contains(KeywordCell))
{
li.Add(KeywordCell);
}
}
}
One minor thing to try once you've dealt with the larger issues pointed out by the others...
You're calculating ssl[a3].ToString() 8 times for each time through the inner loop. That's 40,000 times for each value of a3. You can pre-calculate the string values of each item in a3 and store them in a List before the outer loop. Then, instead of iterating over the index off ssl in the inner loop, use a foreach on the values of your pre-calculated list of strings.
If you do this, you will need to move the code in the if (a3 == (ssl.Count-1)) out of the inner loop to the end of the outer loop.