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.
Related
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.
Okay, so i'm trying to get 18 "prices" from my database in SQL, then setting them in a local array. So far i have this logic in the data retrieval:
private void dbPrices()
{
string myConnectionString;
myConnectionString = "server=127.0.0.1;uid=root;" +
"pwd=;database=phvpos";
try
{
conn = new MySql.Data.MySqlClient.MySqlConnection();
conn.ConnectionString = myConnectionString;
conn.Open();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show(ex.Message);
}
for (int i = 1; i < 19; i++)
{
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT price from products where id = '" + i + "'";
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
pr[i] = reader.ToString();
prods[i] = int.Parse(pr[i]);
}
}
}
And this logic in getting the total amount:
private void btnTotal_Click(object sender, EventArgs e)
{
dbPrices();
itemcost[0] = Convert.ToInt32(txtRice.Text) * prods[0];
itemcost[1] = Convert.ToInt32(txtAdobo.Text) * prods[1];
itemcost[2] = Convert.ToInt32(txtIgado.Text) * prods[2];
itemcost[3] = Convert.ToInt32(txtSisig.Text) * prods[3];
...
itemcost[18] = itemcost[0] + itemcost[1] + itemcost[2] + itemcost[3] + itemcost[4] + itemcost[5]
+ itemcost[6] + itemcost[7] + itemcost[8] + itemcost[9] + itemcost[10]
+ itemcost[11] + itemcost[12] + itemcost[13] + itemcost[14] + itemcost[15]
+ itemcost[16] + itemcost[17];
int totalPrice = itemcost[18];
lblTotal.Text = Convert.ToString(totalPrice);
}
this line in dbPrices() spits out a 'input string was not in a correct format' error:
while (reader.Read())
{
pr[i] = reader.ToString();
prods[i] = int.Parse(pr[i]);
}
I have also tried:
while (reader.Read())
{
prods[i] = Convert.toInt32(reader.ToString());
}
But also spits the same error. Is there anything that i'm doing wrong?
Try this. I find that when using 'reader' that even when your query only grabs one value you still need to specify what value your looking for.
prods[i] = int.Parse(reader["price"]);
and if price is nullable in the database use a ternary operator
prods[i] = reader["price"] == DBNull.Value ? 0 : int.parse(reader["price"]);
The value from your result needs to convert to int and your for loop block might cause you serious problem in the future, you might want to have a projection query and then assign the values of the result.
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = $"SELECT price FROM products WHERE id BETWEEN 1 AND 18"; //use projection. if you have a dynamic product id set, you can use IN in query.
MySqlDataReader reader = cmd.ExecuteReader();
var counter = 0; //counter
while (reader.Read())
{
prods[counter] = Convert.ToInt32(reader["price"]); //convert the result first then assign it to the item.
counter++;
}
I need a way to check if a table exist in my database from my C# class, and if that table got the rows needed.
If it doesn't exist or some of the rows are missing, I need to add those.
I've used this method but don't know how to get the missing functions in there.
( Check if a SQL table exists )
I'm working with SQL Server and C#
I'm going to attach a script here that will dump all the objects and columns for the objects in a TempTable. I run the same script on the DB that I'm comparing with, and check which objects doesn't exists, and which columns in which tables does not exist, and which columns have changed. I've used a Delphi app very long ago then to "upgrade" my DB's
I run this code on the MASTER database.
If Exists(Select 1 from sysobjects where name = 'CheckTables')
Drop Table CheckTables
GO
Select o.id oid, o.name oname, c.colid cid, c.name cname, t.name ctype, c.xusertype, c.[length] tlength, c.prec cprec, c.scale cscale, isnullable
into CheckTables
from sysobjects o
inner join syscolumns c on c.id = o.id
inner join systypes t on t.xusertype = c.xusertype
where o.name not like '%dt_%' and o.category <> 2 and o.type = 'U'
order by o.id, c.colid
Delete CheckTables where oname = 'CheckTables'
Then I bcp the data into a flat file
When I ran my upgrade, I create a table on the Upgrade DB with the same structure, and bcp the data of the Master DB in there.
Then I used this script then in my Delphi App to check what changed.
Select oname, cname, ctype, IsNull(tlength, 0), IsNull(cprec, 0), IsNull(cscale, 0), ctype, isnullable from CheckTables hr
where cname not in (Select name from syscolumns where id = object_id(oname)
and length = hr.tlength
and xusertype = hr.xusertype
and isnullable = hr.isnullable)
order by oname
This should get you going.
If you need more information on the C# part of it, I can give you some code.
Here is C# code to get you going. There is some stuff that you will have to add yourself, but if you strugle, let me know.
private void UpgradeDB()
{
SqlConnection conn = new SqlConnection("Some Connection String");
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
conn.Open();
cmd.CommandText = "If 1 = (Select 1 from sysobjects where id = object_id('CheckTables'))\r\n" +
" Drop Table CheckTables\r\n" +
"Create Table CheckTables\r\n" +
"(oid int,\r\n" +
"oname varchar(50),\r\n" +
"colid int,\r\n" +
"cname varchar(50),\r\n" +
"ctype varchar(50),\r\n" +
"cxtype int,\r\n" +
"tlength int,\r\n" +
"cPrec int,\r\n" +
"cScale int,\r\n" +
"isnullable int";
cmd.ExecuteNonQuery();
//BCP your data from MASTER TABLE into the CheckTables of the UpgradeDB
cmd.CommandText = "Select oname, cname, ctype, IsNull(tlength, 0), IsNull(cprec, 0), IsNull(cscale, 0), isnullable from CheckTables hr\r\n" +
"where cname not in (Select name from syscolumns where id = object_id(oname)\r\n" +
"and length = hr.tlength\r\n" +
"and xusertype = hr.xusertype\r\n" +
"and isnullable = hr.isnullable)\r\n" +
"order by oname";
SqlDataReader read = cmd.ExecuteReader();
string LastTable = "";
bool TableExists = false;
bool ColumnExists = false;
while(read.Read())
{
if(LastTable != read[0].ToString())
{
LastTable = read[0].ToString();
TableExists = false;
if (!CheckIfTableExist(LastTable))
TableExists = CreateTable(LastTable);
else
TableExists = true;
}
if (TableExists)
{
if (!CheckIfColumnExists(read[0].ToString(), read[1].ToString()))
{
CreateColumn(read[0].ToString(), read[1].ToString(), read[2].ToString(),
Convert.ToInt32(read[3].ToString()), Convert.ToInt32(read[4].ToString()),
Convert.ToInt32(read[5].ToString()), Convert.ToBoolean(read[6].ToString()));
ColumnExists = false; //You don't want to alter the column if you just created it
}
else
ColumnExists = true;
if(ColumnExists)
{
AlterColumn(read[0].ToString(), read[1].ToString(), read[2].ToString(),
Convert.ToInt32(read[3].ToString()), Convert.ToInt32(read[4].ToString()),
Convert.ToInt32(read[5].ToString()), Convert.ToBoolean(read[6].ToString()));
}
}
}
read.Close();
read.Dispose();
conn.Close();
cmd.Dispose();
conn.Dispose();
}
private bool CheckIfTableExist(string TableName)
{
SqlConnection conn = new SqlConnection("Connection String");
SqlCommand cmd = new SqlCommand();
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "Select IsNull(object_id('" + TableName + "'), 0)";
Int64 check = Convert.ToInt64(cmd.ExecuteScalar());
conn.Close();
cmd.Dispose();
conn.Dispose();
return check != 0;
}
private bool CreateTable(string TableName)
{
try
{
//Write your code here to create your table
return true;
}
catch
{
return false;
}
}
private bool CheckIfColumnExists(string TableName, string ColName)
{
SqlConnection conn = new SqlConnection("Connection String");
SqlCommand cmd = new SqlCommand();
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "Select IsNull(id, 0) from syscolumns where id = object_id('" + TableName + "') and name = '" + ColName + "'";
Int64 check = Convert.ToInt64(cmd.ExecuteScalar());
conn.Close();
cmd.Dispose();
conn.Dispose();
return check != 0;
}
private void CreateColumn(string TableName, string ColName, string ColType, int Length, int Precision, int Scale, bool Nullable)
{
//Write your code here to create your column
}
private void AlterColumn(string TableName, string ColName, string ColType, int Length, int Precision, int Scale, bool Nullable)
{
//Write your code here to alter your column
}
I have to search the employee details, which is contained within 3 tables. I have used joins in the query query, but it shows error when I press the search button:
sql command not properly ended
c# coding:
try {
//Search Employee Details
Oracle.DataAccess.Client.OracleConnection cn = new Oracle.DataAccess.Client.OracleConnection();
cn.ConnectionString = "user id=system; password=system;";
Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand();
cmd.Connection = cn;
//cn = new Oracle.DataAccess.Client.OracleConnection();
cmd.CommandText = " select deposit.loanid,
form1.empedoj,
form1.empshare,
sharecapital.shareint,
sharecapital.loandt,
sharecapital.loandeduc,
sharecapital.dividend,
sharecapital.sharetot
from form1,
deposit,
sharecapital
where deposit.loanid(+) = sharecapital.loanid = '" + txtlnid.Text.Trim() + "'"; // shows sql command not properly ended
Oracle.DataAccess.Client.OracleDataAdapter ada = new Oracle.DataAccess.Client.OracleDataAdapter(cmd);
System.Data.DataTable dt = new DataTable();
dt.Clear();
ada.Fill(dt);
//Display in Textbox
if (dt.Rows.Count > 0) {
txtlnid.Text = dt.Rows[0].ItemArray[0].ToString();
admdate.Text = dt.Rows[0].ItemArray[1].ToString();
txtadmamt.Text = dt.Rows[0].ItemArray[2].ToString();
txtadmint.Text = dt.Rows[0].ItemArray[3].ToString();
loandt.Text = dt.Rows[0].ItemArray[4].ToString();
txtlnamt.Text = dt.Rows[0].ItemArray[5].ToString();
txtlnint.Text = dt.Rows[0].ItemArray[6].ToString();
txtsctot.Text = dt.Rows[0].ItemArray[7].ToString();
}
if (cn.State == ConnectionState.Closed) {
cn.Open();
}
string str;
str = cmd.ExecuteScalar().ToString();
if (str != null) {
MessageBox.Show("Record Found");
} else {
MessageBox.Show("ID not Match");
}
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
Your SQL statement becomes
SELECT DEPOSIT.LOANID,
FORM1.EMPEDOJ,
FORM1.EMPSHARE,
SHARECAPITAL.SHAREINT,
SHARECAPITAL.LOANDT,
SHARECAPITAL.LOANDEDUC,
SHARECAPITAL.DIVIDEND,
SHARECAPITAL.SHARETOT
FROM FORM1, DEPOSIT, SHARECAPITAL
WHERE DEPOSIT.LOANID(+) = SHARECAPITAL.LOANID = '" + txtlnid.Text.Trim() + "'";
I suspect it should be:
SELECT DEPOSIT.LOANID,
FORM1.EMPEDOJ,
FORM1.EMPSHARE,
SHARECAPITAL.SHAREINT,
SHARECAPITAL.LOANDT,
SHARECAPITAL.LOANDEDUC,
SHARECAPITAL.DIVIDEND,
SHARECAPITAL.SHARETOT
FROM FORM1, DEPOSIT, SHARECAPITAL
WHERE DEPOSIT.LOANID(+) = SHARECAPITAL.LOANID
AND SHARECAPITAL.LOANID = '" + txtlnid.Text.Trim() + "'";
Also, you have a 3-table join without the correct join conditions, the query is highly likely to return a Cartesian product.
Have you tried putting a semicolon at the end of your query string?
cmd.CommandText = " select deposit.loanid, form1.empedoj, form1.empshare,
sharecapital.shareint, sharecapital.loandt, sharecapital.loandeduc,
sharecapital.dividend, sharecapital.sharetot from form1, deposit ,
sharecapital where deposit.loanid(+) = sharecapital.loanid = '" + txtlnid.Text.Trim() + "';";
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.