ExecuteScalar not working in reader? - c#

When I try to get the value of 1 column out of my Database(using ExecuteScalar(), to string or integer nothing works) It crashes at the execution.
Is it because I am using ExecuteScalar() in my open SqlDataReader?
Here is my code, it crashes at iAantal:
SqlCommand get_order = new SqlCommand("SELECT * FROM Factuur WHERE ID = #ID1 OR order_id = #ID2", con);
get_order.Parameters.AddWithValue("#ID1", Session["LastOrderID"].ToString());
get_order.Parameters.AddWithValue("#ID2", Session["LastOrderID"].ToString());
SqlDataReader rdrOrder = get_order.ExecuteReader();
iAantal = 2;
while(rdrOrder.Read())
{
from_db_producten += "<tr>";
sHuidigeDatum = rdrOrder["besteldatum"].ToString();
sLeverdatum = rdrOrder["leverdatum"].ToString();
sToestelID = rdrOrder["item_id"].ToString();
iPrijsPerStuk = Convert.ToInt32(rdrOrder["prijs"]);
SqlCommand check_aantal_toestel = new SqlCommand("SELECT COUNT(item_id) FROM Factuur WHERE ID = #orderID1 OR order_id = #orderID2 AND item_id = #itemID", con);
check_aantal_toestel.Parameters.AddWithValue("#orderID1", Session["LastOrderID"].ToString());
check_aantal_toestel.Parameters.AddWithValue("#orderID2", Session["LastOrderID"].ToString());
check_aantal_toestel.Parameters.AddWithValue("#itemID", sToestelID);
iAantal = Convert.ToInt32(check_aantal_toestel.ExecuteScalar());
SqlCommand get_toestel_merk = new SqlCommand("SELECT item_value FROM ItemSpecificatie WHERE item_key = #merk AND item_id = #ID", con);
get_toestel_merk.Parameters.AddWithValue("#merk", "Merk");
get_toestel_merk.Parameters.AddWithValue("#ID", sToestelID);
SqlCommand get_toestel_naam = new SqlCommand("SELECT item_value FROM ItemSpecificatie WHERE item_key = #naam AND item_id = #ID", con);
get_toestel_merk.Parameters.AddWithValue("#naam", "Naam");
get_toestel_merk.Parameters.AddWithValue("#ID", sToestelID);
sToestelmerk = Convert.ToString(get_toestel_merk.ExecuteScalar());
sToestelnaam = Convert.ToString(get_toestel_naam.ExecuteScalar());
iPrijsTotaal = iAantal * iPrijsPerStuk;
}

As mentioned in your question itself, you cannot perform ExecuteScalar() when you have ExecuteReader() open.
However, you can add MultipleActiveResultSets = true in the connection string provider part to achieve multiple connections to the data source.
However, this is do-able this is not recommended way for database connectivity. Because, opening multiple connections with the data source will cause additional load on the database.

Related

how to find how many rows effected by select query from c#

I want to find how many rows affected when I fire a select query from C#. without insert data into dataset or datatable.
string constr = ConfigurationManager.ConnectionStrings["testConnectionString"].ConnectionString; //get connection string Web.config
SqlConnection con = new SqlConnection(constr);
//define Select Query
SqlCommand slct = new SqlCommand("select * From [dbo].[userdetail] where 1=1", con);
int noRows;
//open connection and execute query
con.Open();
noRows = slct.ExecuteNonQuery();
con.Close();
//define Select Query
SqlCommand select = new SqlCommand("select * From [dbo].[userdetail] where 1=0", con);
//open connection and execute query
con.Open();
noRows = select.ExecuteNonQuery();
con.Close();
First of all for your current query use ExecuteReader() and while reading the loop saying below keep a counter
int count = 0;
while(rdr.Read())
{
count++;
}
Else, use a scalar query like below and use ExecuteScalar() function
select count(*) From [dbo].[userdetail]
SqlCommand cmd = new SqlCommand("select count(*) From [dbo].[userdetail]", con);
// open connection and execute query
con.Open();
int noRows = (int)cmd.ExecuteScalar();

Unable to update database in ASP.NET

I wanted to update a record to the database but it just keep reverting to its original value.
Below is my code. No error was display to me either.
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CandidateConnectionString"].ConnectionString);
conn.Open();
string updateData = "UPDATE Resume SET [Work_Experience] = #work_exp, [Educational_Level] = #edu_level, [Field_Of_Study] = #field_study, [University_Name] = #uni_name, [University_Location] = #uni_locate, [Graduation_Year] = #gra_year WHERE Cand_ID = (SELECT Cand_ID FROM Candidate WHERE Cand_Username = '"+ usernamelbl.Text +"')";
SqlCommand cmd = new SqlCommand(updateData, conn);
cmd.Parameters.AddWithValue("#work_exp", Work_Exp.Text);
cmd.Parameters.AddWithValue("#edu_level", Edu_Level.SelectedItem.Text);
cmd.Parameters.AddWithValue("#field_study", Field_Study.SelectedItem.Text);
cmd.Parameters.AddWithValue("#uni_name", Uni_Name.Text);
cmd.Parameters.AddWithValue("#uni_locate", Uni_Locate.Text);
cmd.Parameters.AddWithValue("#gra_year", Year.Text);
cmd.ExecuteNonQuery();
conn.Close();
Any Problem with the code?
I just found out a stupid mistake..
On the page_Load event, I have a line of code which is fetching value from the database
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CandidateConnectionString"].ConnectionString);
conn.Open();
string getdata = "SELECT * FROM Resume WHERE Cand_ID = (SELECT Cand_ID FROM Candidate WHERE Cand_Username = '" + usernamelbl.Text + "')";
SqlCommand com = new SqlCommand(getdata, conn);
SqlDataAdapter sda = new SqlDataAdapter(com);
DataSet ds = new DataSet();
sda.Fill(ds, "Resume");
Work_Exp.Text = ds.Tables["Resume"].Rows[0]["Work_Experience"].ToString();
Edu_Level.Text = ds.Tables["Resume"].Rows[0]["Educational_Level"].ToString();
Field_Study.Text = ds.Tables["Resume"].Rows[0]["Field_Of_Study"].ToString();
Uni_Name.Text = ds.Tables["Resume"].Rows[0]["University_Name"].ToString();
Uni_Locate.Text = ds.Tables["Resume"].Rows[0]["University_Location"].ToString();
Year.Text = ds.Tables["Resume"].Rows[0]["Graduation_Year"].ToString();
conn.Close();
But I didn't include it under if(!IsPostBack) and that's the reason whenever I submit, it overwrites my current value and revert it back to the original state. Thanks to you guys who trying to help me sort out and teaches me about new stuff. :)

C# Error: "Fill: SelectCommand.Connection property has not been initialized."

I'm using this video to try and populate results from a DataGridView, and am receiving the above error. The below code pertains to this error - I pass values into a stored procedure, then the final SELECT returns the values in the table in the DataGridView.
SqlConnection con = new SqlConnection();
con.ConnectionString = "integrated security=SSPI;data source=SERV;" + "persist security info=False;initial catalog=DB";
con.Open();
SqlCommand select = new SqlCommand("SELECT * FROM Table");
SqlCommand enter = new SqlCommand("sp_Proc", con);
// Stored Procedure
enter.CommandType = CommandType.StoredProcedure;
enter.Parameters.Add(new SqlParameter("#vvalue", SqlDbType.VarChar)).Value = Convert.ToString(txt1.Text);
enter.Parameters.Add(new SqlParameter("#dvalue", SqlDbType.Decimal)).Value = Convert.ToDecimal(txt2.Text);
enter.ExecuteNonQuery();
// DataGrid returns the SELECT
SqlDataAdapter sadapt = new SqlDataAdapter(select);
sadapt.SelectCommand = select;
DataTable dtab = new DataTable();
sadapt.Fill(dtab); // generates the error
BindingSource b = new BindingSource();
b.DataSource = dtab;
dGrid.DataSource = b;
sadapt.Update(dtab);
con.Close();
You did not pass connection object on the command. Try this instead,
SqlCommand select = new SqlCommand("SELECT * FROM Table", con);
You are passing connection object to your enter command but didnt pass the connection object to your select command
SqlCommand select = new SqlCommand("SELECT * FROM Table");
SqlCommand enter = new SqlCommand("sp_Proc", con);
Use this
SqlCommand select = new SqlCommand("SELECT * FROM Table",con);
SqlCommand cmd = new SqlCommand("sp_StockAnalysis2") // connection missing in sqlcommand
SqlCommand cmd = new SqlCommand("sp_StockAnalysis2",Connection())// pass connection

OutOfMemoryException in my application, I tried to use using and dispose()!

I've just read all the answers about the same problem but they have not helped.
This is a part of my c# code that is too long. It has a lot of SQLConnections and 2 timers.
Indirizzo nuovoInd = new Indirizzo();
SqlConnection cn = new SqlConnection(nuovoInd.OttieniIP());
string strSql = "INSERT INTO Pietanze(nome,prezzo,ingredienti,cod_cat) VALUES ('"+nome+"','"+prezzo+"','"+ingredienti+"','"+contCat+"')";
SqlCommand cmd = new SqlCommand(strSql, cn);
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
or
public static float GetCoperti(int codOrdine)
{
float copertiTot = 0;
List<Ordine> ordini = new List<Ordine>();
VisualizzaOrdini.Form1.Indirizzo nuovoInd = new VisualizzaOrdini.Form1.Indirizzo();
SqlConnection cn = new SqlConnection(nuovoInd.OttieniIP());
string strSql = "SELECT codo,tavolo,InsertDate,nCoperti,costoCoperti FROM Ordini, Riga_Ordine, Coperti where codo=cod_or and cod_or = '"+ codOrdine + "' ORDER BY InsertDate DESC";
SqlCommand cmd = new SqlCommand(strSql, cn);
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Ordine currO = new Ordine();
currO.Data = Convert.ToDateTime(dr["InsertDate"]);
currO.Coperti = (int)dr["nCoperti"];
currO.PrezzoCoperto = Convert.ToSingle(dr["costoCoperti"]);
currO.Tavolo = dr["tavolo"].ToString();
currO.Codice = (int)dr["codo"];
copertiTot = (currO.PrezzoCoperto * Convert.ToSingle(currO.Coperti));
ordini.Add(currO);
}
return copertiTot;
}
I'm struggling with the fact that the code is throwing an OutOfMemoryException. What might be causing this? How do I resolve it?
It may be the problem that you are not Closing your SqlDataReader object after fetching records, You have to close it explicitly.
dr.Close();
And also, Close your connection after closing reader, or use using block as suggested by Habib.
cn.Close();
First, having your database connection open for the full execution of code is bad practice. Assign the execute statement to some DataTable. It will provide you the local copy of the database. It's also more convenient to process and you surely don't get out of memory exceptions.
Datatable DTab = cmdexecuteReader();
DataSet DSet = cmdexecuteReader();
Both Will give you expectedd results always.

How to get a value in another table, store it in a variable or data reader, and then use it to update another table

does anyone know how do I get the StudentID from Students table, store it in datareader or dataset, and then use it to update another table, which is Users Table, because I want the username and password of users would be their StudentID as a default. BTW, this is C# ASP.NET.
Here is my code.
SqlConnection conUpdate = new SqlConnection(GetConnectionString());
conUpdate.Open();
SqlCommand com2 = new SqlCommand();
com2.Connection = conUpdate;
com2.CommandText = "SELECT Students.StudentID, Users.UserID FROM Students, Users " +
"WHERE Students.UserID = Users.UserID";
int UserId = ((int)com2.ExecuteScalar());
com2.CommandText = "SELECT MAX(StudentID) FROM Students";
int StudentId = ((int)com2.ExecuteScalar());
com2.CommandType = CommandType.Text;
com2.CommandText = "UPDATE Users SET UserName=#UserName, Password=#Password WHERE UserID=#UserID";
com2.Parameters.Add("#UserName", SqlDbType.NVarChar);
com2.Parameters.Add("#Password", SqlDbType.NVarChar);
com2.Parameters[0].Value = reader;
com2.Parameters[1].Value = reader;
com2.ExecuteNonQuery();
conUpdate.Close();
conUpdate.Dispose();
Since you already getting UserId in your select query, you should get the value using DataReader. like this:
// Execute the query
SqlDataReader rdr = cmd.ExecuteReader();
int UserId;
while(rdr.Read())
{
UserId = Convert.ToInt32(rdr["UserID"].ToString());
}
Your command com2.CommandText = "SELECT MAX(StudentID) FROM Students"; will return the Max student ID, and that is probably not needed. Your earlier command com2.CommandText = "SELECT Students.StudentID, Users.UserID .... is what you need to get the student UserID.
You can use Data reader (Connection oriented) like below:
SqlDataReader reader = com2.ExecuteReader();
while (reader.Read())
{
int UserId = Convert.ToInt(reader[0]);// or reader["UserID"]
}
reader.Close();
Or you can use DataAdapter (disconnected mode) like:
SqlDataAdapter a = new SqlDataAdapter(com2, connection);
DataTable dt = new DataTable();
a.Fill(dt);
Now your dt.Rows["UserID"] will have the UserID you need.
You may wanna see this: http://www.dotnetperls.com/sqldataadapter
If I understood you correctly, I think the following code might work. Or in the least give you an idea about how you can go about it. Am assuming that you want each student's UserName and Password to default to their StudentID
SqlConnection conUpdate = new SqlConnection(GetConnectionString());
conUpdate.Open();
SqlCommand com2 = new SqlCommand();
com2.Connection = conUpdate;
com2.CommandType = CommandType.Text;
com2.CommandText = "SELECT Students.StudentID, Users.UserID FROM Students, Users " +
"WHERE Students.UserID = Users.UserID";
SqlDataReader reader = com2.ExecuteReader();
if(reader != null)
{
while(reader.Read())
{
SqlCommand com3 = new SqlCommand();
com3.Connection = conUpdate;
com3.CommandType = CommandType.Text;
com3.CommandText = "UPDATE Users SET UserName=#UserName, Password=#Password WHERE UserID=#UserID";
// Assuming that you need both the UserName and Password to default to StudentID
com3.Parameters.AddWithValue("#UserName", reader.GetString(0)); // Assuming StudentID is NVARCHAR
com3.Parameters.AddWithValue("#Password", reader.GetString(0)); // Assuming StudentID is NVARCHAR
com3.Parameters.AddWithValue("#UserID", reader.GetString(1)); // Assuming UserID is NVARCHAR
com3.ExecuteNonQuery();
}
reader.Close();
}
conUpdate.Close();

Categories