I have two table.I need to get calorificValue from the food table and daily_gained from the calorie_tracker table to then make some calculations.I've written this code, I know it not efficent. It retrieves daily_gained but failed to get calorificValue.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
MySqlCommand cmd2 = new MySqlCommand("SELECT sportsman_id,daily_gained FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
cmd2.Connection.Open();
MySqlDataReader rd = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
int burned = 0;
if (rd.HasRows) // if entered username and password have the data
{
while (rd.Read()) // while the reader can read
{
if (rd["sportsman_id"].ToString() == Login.userID) // True for admin
{
burned += int.Parse(rd["daily_gained"].ToString());
}
}
}
cmd2.Connection.Close();
cmd.Connection.Open();
MySqlDataReader rd2 = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (rd2.HasRows) // if entered username and password have data
{
while (rd2.Read()) // while the reader can read
{
if (rd2["name"].ToString() == s)
{
burned += int.Parse(rd2["calorificValue"].ToString());
}
}
}
MessageBox.Show(burned+"");
DataTable tablo = new DataTable();
string showTable = "SELECT * from myfitsecret.calorie_tracker where sportsman_id=#sportsman_id";
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand showCommand = new MySqlCommand();
showCommand.Connection = cnn;
showCommand.CommandText = showTable;
showCommand.CommandType = CommandType.Text;
showCommand.Parameters.AddWithValue("#sportsman_id", Login.userID);
adapter.SelectCommand = showCommand;
adapter.Fill(tablo);
dataGridView1.DataSource = tablo;
cnn.Close();
Why don't you just use the scalar function SUM and let the database do its job instead of writing a lot of code?
int burned = 0;
string s = comboBox1.SelectedItem.ToString();
cnn.Open();
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
cmdText = #"SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
Not visible from your code, but also the connection should be created inside a using statement (very important with MySql that is very restrictive with simultaneous open connections)
We could also use a different approach putting the two commands together and separating them with a semicolon. This is called batch commands and they are both executed with just one trip to the database. Of course we need to fallback using the MySqlDataReader to get the two results passing from the first one to the second one using the NextResult() method (see here MSDN for Sql Server)
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name;
SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
// Add both parameters to the same command
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
cnn.Open();
using(MySqlDataReader reader = cmd.ExecuteReader())
{
// get sum from the first result
if(reader.Read()) burned += Convert.ToInt32(reader[0]);
// if there is a second resultset, go there
if(reader.NextResult())
if(reader.Read())
burned += Convert.ToInt32(reader[0]);
}
}
Your issues could be around closing a connection and then trying to open it again. Either way it's fairly inefficient to be closing and opening connections.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
MySqlCommand cmd2 = new MySqlCommand("SELECT SUM(daily_gained) FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
cnn.Open();
MySqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows) // if entered username and password have data
{
while (rd.Read()) // while the reader can read
{
burned += int.Parse(rd["calorificValue"].ToString());
}
}
burned = cmd2.ExecuteScalar();
MessageBox.Show(burned+"");
cnn.Close();
Related
I am trying to store sql data that I have for a voucher id and voucher amount into a variable and display it into a label on a click of a button.
protected void Button1_Click(object sender, EventArgs e)
{
string voucherId = String.Empty;
string voucherAmount = String.Empty;
string queryVoucherId = "select voucherid from ReturnForm where email = '" + Session["username"] + "';";
string queryVoucherAmount = "select voucheramount from ReturnForm where email = '" + Session["username"] + "';";
int index = 0;
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherId, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherId = reader[index].ToString();
index++;
}
}
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherAmount, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherAmount = reader[index].ToString();
index++;
}
}
if (txtVoucher.Text == voucherId)
{
Label3.Visible = true;
Label3.Text = voucherAmount;
}
}
When I click the button its giving me an error saying that the index is out of bounds.
Building on #JSGarcia's answer - but using parameters as one ALWAYS should - you'd get this code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom WHERE Email = #email";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
// set the parameter before opening connection
// this also defines the type and length of parameter - just a guess here, might need to change this
cmd.Parameters.Add("#email", SqlDbType.VarChar, 100).Value = email;
conn.Open();
sda.Fill(dt);
conn.Close();
}
Personally, I'd rather use a data class like
public class VoucherData
{
public int Id { get; set; }
public Decimal Amount { get; set; }
}
and then get back a List<VoucherData> from your SQL query (using e.g. Dapper):
string query = $"SELECT Id, Amount FROM ReturnFrom WHERE Email = #email";
List<VoucherData> vouchers = conn.Query<VoucherData>(query).ToList();
I'd try to avoid the rather clunky and not very easy to use DataTable construct...
I strongly recommend combining your sql queries into a single one, write it into a datatable and continue your logic from there. IMHO it is much cleaner code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom where Email = '{email}'";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = conn.CreateCommand())
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
conn.Open();
sda.Fill(dt);
conn.Close();
}
// Work with DataTable dt from here on
...
Well, one more big tip?
You ONLY as a general rule need a dataadaptor if you going to update the data table.
And you ONLY need a new connection object if you say not using the sql command object.
The sqlcommand object has:
a connection object - no need to create a separate one
a reader - no need to create a separate one.
Note how I did NOT create a seperate connection object, but used the one built into the command object.
And since the parameter is the SAME in both cases? Then why not re-use that too!!
So, we get this:
void TestFun2()
{
String str = "some conneciton???";
DataTable rstVouch = new DataTable();
using (SqlCommand cmdSQL =
new SqlCommand("select voucherid from ReturnForm where email = #email",
new SqlConnection(str)))
{
cmdSQL.Parameters.Add("#email", SqlDbType.NVarChar).Value = Session["username"];
cmdSQL.Connection.Open();
rstVouch.Load(cmdSQL.ExecuteReader());
// now get vouch amount
cmdSQL.CommandText = "select voucheramount from ReturnForm where email = #email";
DataTable rstVouchAmount = new DataTable();
rstVouchAmount.Load(cmdSQL.ExecuteReader());
if (rstVouch.Rows[0]["vourcherid"].ToString() == txtVoucher.Text)
{
Label3.Visible = true;
Label3.Text = rstVouchAmount.Rows[0]["voucheramount"].ToString();
}
}
}
I'm using C# console app to update a table with a lot of rows based on the value of two column inside MySQL.
Below is the code that I've tried to update the table.
Is it possible to execute update during dataread while loop or do I need to use other way to accomplish this?
int currentPoints;
int shudhavePoints;
string email;
MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnectionString"].ConnectionString);
con.Open();
MySqlCommand cmd1 = new MySqlCommand("SELECT user_email, meta_value AS 'Current Points', point FROM wp_usermeta", con);
MySqlDataReader rdr = null;
rdr = cmd1.ExecuteReader();
if(rdr.HasRows)
{
while(rdr.Read())
{
email = rdr.GetString(0);
currentPoints = Int32.Parse(rdr.GetString(1));
shudhavePoints = Int32.Parse(rdr.GetString(2));
if (currentPoints>shudhavePoints)
{
// I want to update here
MySqlCommand cmd2 = new MySqlCommand("UPDATE TABLE wp_usermeta SET meta_value = #cp WHERE user_email = #email", con);
cmd2.Parameters.AddWithValue("#cp", shudhavePoints);
cmd2.Parameters.AddWithValue("#email",email);
cmd2.ExecuteNonQuery();
}
}
Console.ReadLine();
}
else
{
Console.WriteLine("I read nothing!");
Console.ReadLine();
}
Right now if I execute the programs, the data will not be updated and will show error
'There is already an open DataReader associated with this Connection which must be closed first.'
However if I close the connection, it will only execute and update the very first row which satisfy the if-else rule.
I think there must be a way for this to run in a loop without having me to run the program repeating times.
Can anyone suggest how should I fix the code for that?
U can define new connection object for that
int currentPoints;
int shudhavePoints;
string email;
MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnectionString"].Connection
String);
MySqlConnection con1 = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnectionString"].Connection
String);
con.Open();
MySqlCommand cmd1 = new MySqlCommand("SELECT user_email, meta_value AS 'Current Points', point FROM wp_usermeta", con);
MySqlDataReader rdr = null;
rdr = cmd1.ExecuteReader();
if(rdr.HasRows)
{
while(rdr.Read())
{
email = rdr.GetString(0);
currentPoints = Int32.Parse(rdr.GetString(1));
shudhavePoints = Int32.Parse(rdr.GetString(2));
if (currentPoints>shudhavePoints)
{
// I want to update here
MySqlCommand cmd2 = new MySqlCommand("UPDATE TABLE wp_usermeta SET meta_value = #cp WHERE user_email = #email", con1);
cmd2.Parameters.AddWithValue("#cp", shudhavePoints);
cmd2.Parameters.AddWithValue("#email",email);
cmd2.ExecuteNonQuery();
}
}
Console.ReadLine();
}
else
{
Console.WriteLine("I read nothing!");
Console.ReadLine();
}
int currentPoints;
int shudhavePoints;
string email;
MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnectionString"].ConnectionString);
con.Open();
MySqlCommand cmd1 = new MySqlCommand("SELECT user_email, meta_value AS 'Current Points', point FROM wp_usermeta", con);
MySqlDataReader rdr = null;
rdr = cmd1.ExecuteReader();
if(rdr.HasRows)
{
while(rdr.Read())
{
email = rdr.GetString(0);
currentPoints = Int32.Parse(rdr.GetString(1));
shudhavePoints = Int32.Parse(rdr.GetString(2));
if (currentPoints>shudhavePoints)
{
//I want to update here
MySqlCommand cmd2 = new MySqlCommand("UPDATE TABLE wp_usermeta SET meta_value = #cp WHERE user_email = #email", con);
cmd2.Parameters.AddWithValue("#cp", shudhavePoints);
cmd2.Parameters.AddWithValue("#email",email);
cmd2.ExecuteNonQuery();
}
if(!rdr.read())
{
Console.WriteLine("Update query not working!!!");
}
else
{
//user_email
string usermail = Convert.ToString(user_email);
usermail = rdr[0].ToString();
Console.WriteLine("Username: {0}", usermail.ToString());
//meta_value AS 'Current Points'
string metavalue = Convert.ToString(meta_value);
metavalue = rdr[1].ToString();
Console.WriteLine("metavalue: {0}", metavalue.ToString());
//meta_value AS 'point'
string points = Convert.ToString(point);
points = rdr[2].ToString();
Console.WriteLine("point: {0}", points.ToString());
Console.ReadLine();
}
}
Console.ReadLine();
}
else
{
Console.WriteLine("I read nothing!");
Console.ReadLine();
}
Hi i have Attendance and Departure System on mvc Using Ado.Net My Connection Name is (DBConnection) i have Two Method One For OnClick TimeIn and AND OTHER one for TimeOut , My DataBase Name LoginTime and My Table is Attendance I have Problem in onclick timein Btton check if row not exist in my Attendance table insert new row else show Message "You Already TimeIn"
public void Addtime(Attendance AddTim)
{
SqlCommand comm = new SqlCommand("select * from Attendance where UserID=#user", conn);
comm.Parameters.AddWithValue("#user", AddTim.UserID);
conn.Open();
var rd = comm.ExecuteReader();
bool sat = rd.Read();
conn.Close();
if (sat == true)
{
SqlCommand updCommand = new SqlCommand("UPDATE Attendance SET TimeIn=#timein WHERE UserID=#userid", conn);
updCommand.Parameters.AddWithValue("#userid", AddTim.UserID);
updCommand.Parameters.AddWithValue("#timein", DateTime.Now);
conn.Open();
int rowsUpdated = updCommand.ExecuteNonQuery();
var rdr = comm.ExecuteReader();
conn.Close();
}
else
{
SqlCommand insCommand = new SqlCommand("INSERT into Attendance (UserID,TimeIn) VALUES (#userid,#timein)", conn);
insCommand.Parameters.AddWithValue("#userid", AddTim.UserID);
insCommand.Parameters.AddWithValue("#timein", DateTime.Now);
conn.Open();
int rowsUpdated = insCommand.ExecuteNonQuery();
var rdr = comm.ExecuteReader();
conn.Close();
}
}
public void Addtimout(Attendance addtimout)
{
SqlCommand UpDCommand = new SqlCommand("UPDATE Attendance SET TimeOut=#timeout WHERE UserID=#userid", conn);
UpDCommand.Parameters.AddWithValue("#UserID", addtimout.UserID);
UpDCommand.Parameters.AddWithValue("#timeout", DateTime.Now);
conn.Open();
UpDCommand.ExecuteNonQuery();
conn.Close();
}
}
}
There is probably more going on then what I can deduce from your question and no real explanation of the error (if any) you are getting. If this is so please post the error or unexpected behavior, and the database schema would also be helpful
I did notice that you are doing multiple insert or update statements in that block, as you are executing each query twice; once as a NonQuery and again as a Reader.
int rowsUpdated = insCommand.ExecuteNonQuery();
var rdr = comm.ExecuteReader();
The original query to check doesn't look to great to me. If you simply want to check for a row count, you could use SELECT Count(*), and execute via ExecuteScalar(). This will remove the overhead of a Reader
public void Addtime(Attendance AddTim) {
SqlCommand comm = new SqlCommand("select Count(*) from Attendance where UserID=#user", conn);
comm.Parameters.AddWithValue("#user", AddTim.UserID);
conn.Open();
int uc = (int)comm.ExecuteScalar();
bool sat = (uc > 0);
conn.Close();
I have question about using why i can not use the same instance of SQLCommand more than one time in the same code?
I tried the code down here and it runs good for the gridview but when i changed the query by using cmd.CommandText() method it keeps saying:
There is already an open DataReader associated with this Command which must be closed first.
This is the code:
string cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Select top 10 FirstName, LastName, Address, City, State from Customers";
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
finally
{
con.Close();
}
The problem is that you are using the SqlCommand object to generate a DataReader via the command.ExecuteReader() command. While that is open, you can't re-use the command.
This should work:
using (var reader = cmd.ExecuteReader())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
//now the DataReader is closed/disposed and can re-use command
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
There is already an open DataReader associated with this Command which must be closed first.
This is the very reason you don't share a command. Somewhere in your code you did this:
cmd.ExecuteReader();
but you didn't leverage the using statement around the command because you wanted to share it. You can't do that. See, ExecuteReader leaves a connection to the server open while you read one row at a time; however that command is locked now because it's stateful at this point. The proper approach, always, is this:
using (SqlConnection c = new SqlConnection(cString))
{
using (SqlCommand cmd = new SqlCommand(sql, c))
{
// inside of here you can use ExecuteReader
using (SqlDataReader rdr = cmd.ExecuteReader())
{
// use the reader
}
}
}
These are unmanaged resources and need to be handled with care. That's why wrapping them with the using is imperative.
Do not share these objects. Build them, open them, use them, and dispose them.
By leveraging the using you will never have to worry about getting these objects closed and disposed.
Your code, written a little differently:
var cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
var gridSql = "Select top 10 FirstName, LastName, Address, City, State from Customers";
var cntSql = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
try
{
using (SqlCommand cmd = new SqlCommand(gridSql, con))
{
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
}
using (SqlCommand cmd = new SqlCommand(cntSql, con))
{
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
}
Thank u quys but for the guys who where talking about using block !
why this code work fine which i seen it on example on a video ! It's the same thing using the same instance of SqlCommand and passing diffrent queries by using the method CommanText with the same instance of SqlCommand and it's execute just fine , this is the code :
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Delete from tbleProduct where ProductID= 4";
int TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "Insert into tbleProduct values (4, 'Calculator', 100, 230)";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "ypdate tbleProduct set QtyAvailbe = 234 where ProductID = 2";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
}
I am trying to take a single value from a database, but the cycle does not seem to start at all?
if (connection.State == ConnectionState.Open)
{
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
value = dataReader["amount"].ToString();
}
dataReader.Close();
connection.Close();
}
These are the commands:
public string value;
public static string Konekcija = "Server=127.0.0.1; Database=CardIgrica; Uid=admin; Pwd=admin;";
public string komanda = "SELECT amount FROM CardIgrica.creaures WHERE id = '1';";
MySqlConnection connection = new MySqlConnection(Konekcija);
MySqlCommand cmd = new MySqlCommand(komanda, connection);
connection.Open();
try this for the select
public string value {get; set;}
string komanda ="SELECT amount FROM CardIgrica.creaures WHERE id = 1";
Try this
using (SqlConnection conn = new SqlConnection(Konekcija))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Clear();
cmd.CommandText = komanda ;
conn.Open();
var dataReader= cmd.ExecuteReader();
while (result.Read())
{
value = dataReader["amount"].ToString();
}
conn.Close();
}
If you need single value, you can use cmd.ExecuteScalar(); instead of cmd.ExecuteReader();
because ExecuteScalar() will return single value.
First open your sql connection then make object of MySqlCommand like below:
MySqlConnection connection = new MySqlConnection(Konekcija);
connection.Open();
MySqlCommand cmd = new MySqlCommand(komanda, connection);