I have a database in which I created a table HUGO_BOSS. Its columns are [brand name], [stock quantity], [retail price] and its primery key is [Brand name]. I want to fill my textbox in windows form with the value of stock quantity present in my database. I tried the following code but it gives run-time error
The Connection was not close, the connection state is open.
if (comboBox2.Text == "HUGO BOSS")
{
try
{
OleDbCommand cmd = con.CreateCommand();
cmd.CommandText = "Select [Stock quantity] as stockquantity from HUGO_BOSS WHERE [Brand name]=#name";
cmd.Parameters.AddWithValue("#name", comboBox3.SelectedItem);
con.Open();
OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (dr.Read())
{
textBox7.Text = dr["stockquantity"].ToString();
}
}
finally { con.Close(); }
}
One more thing, here I will select the primary key by using a combobox3
It looks you're trying to reuse a database connection that is already open.
You could try testing the connection state before trying to open it:
OleDbCommand cmd = con.CreateCommand();
cmd.CommandText = "Select [Stock quantity] as stockquantity from HUGO_BOSS WHERE [Brand name]=#name";
cmd.Parameters.AddWithValue("#name", comboBox3.SelectedItem);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.SingleResult);
if (dr.Read())
{
textBox7.Text = dr["stockquantity"].ToString();
}
Alternatively, you could create a new connection each time you need to execute a new command.
Related
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 failed to get the correct result with this code in Form2:
conn.Open();
OleDbCommand cmd = new OleDbCommand("Select * From udbTable Where Username Like '" + f1.textBox1.Text + "%'", conn);
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
label5.Text = reader["Username"].ToString();
}
conn.Close();
I have 3 samples data in the table, but i'm always getting the same result which is the first entry of the database. Whenever i input the last entry or second entry in the textbox1.Text, i still getting the first entry.
textbox1.Text is from Form1, and i set it's property Modification to Public.
label5.text is the output.
try this fix
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection=conn;
command.CommandText = "Select * From udbTable Where Username Like ?";
cmd.Parameters.Add("#Username",OleDbType.VarChar);
cmd.Parameters["#Username"].Value=f1.textBox1.Text;
OleDbDataReader reader = cmd.ExecuteReader();
I am trying to code a register application form. In the code below I want to check if the username exists before i save the data in Database.
The problem here that the code doesn't go to the "else" statement.
Do I miss something? Kindly help
public void UserNameCheck()
{
string connetionString = null;
SqlConnection con;
connetionString = "Data Source=MCOEELIMENEM\\sqlexpress;Initial Catalog=Database;Integrated Security=True";
con = new SqlConnection(connetionString);
SqlCommand cmd = new SqlCommand("Select * from Register where Username= #Username", con);
cmd.Parameters.AddWithValue("#Username", this.textBox1.Text);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr.HasRows == true)
{
MessageBox.Show("Username = " + dr[1].ToString() + " Already exist");
break;
}
else
{
cmd.CommandText = "insert into Register(Username,Password,Fullname,MobileNO,EmailID) values( #Username, #Password, #Fullname, #MobileNO, #EmailID)";
cmd.Parameters.AddWithValue("#Username", textBox1.Text);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
cmd.Parameters.AddWithValue("#Fullname", textBox3.Text);
cmd.Parameters.AddWithValue("#MobileNO", textBox4.Text);
cmd.Parameters.AddWithValue("#EmailID", textBox5.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Data Inserted Succesfully");
con.Close();
this.Hide();
Login lg = new Login();
lg.Show();
}
}
}
The query will not return any rows (therefore the Read() statement will fail) where the user exists.
Try this (untested):
SqlCommand cmd = new SqlCommand("Select count(*) from Register where Username= #Username", con);
cmd.Parameters.AddWithValue("#Username", this.textBox1.Text);
con.Open();
var result = cmd.ExecuteScalar();
if (result != null)
{
MessageBox.Show(string.format("Username {0} already exist", this.textBox1.Text));
}
else
{
...
If dr.Read() returns true, then your reader always has rows.
EDIT:
As long, as you do not getting any values from DB, you can remove while(dr.Read()) statement, and your code will work as you need
I recommand you to not select all columns, instead just select id and check with ExecuteScalar method of SqlCommand, that would be optimum solution.
SqlCommand cmd = new SqlCommand("Select id from Register where Username= #Username", con);
cmd.Parameters.AddWithValue("#Username", this.textBox1.Text);
con.Open();
var nId = cmd.ExecuteScalar();
if(nId != null)
{
// Prompt user is already exists
}
else
{
// Insert record
}
You must check with the number of rows returned by the query.
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 get all the details of a User in an Access database. But i cant seem to save each columns value to a label. Here is the code i am using.
Also UserId has a value assigned to it already
string connString = (#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=DataDirectory|HorseDB.mdb");
OleDbConnection conn = new OleDbConnection(connString);
conn.Open();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = #"SELECT * FROM [Users] WHERE [UserId] = #UserId ";
cmd.Parameters.AddWithValue("#UserId", UserId);
OleDbDataReader dbReader = cmd.ExecuteReader();
while (dbReader.Read())
{
accountUserIdLabel.Text = dbReader.GetValue(0).ToString();
//Will add other labels once this works
}
dbReader.Close();
conn.Close();