I have a method to check if the id exists in a table and if it does insert into another database table; additionally I have label that will display the number of data entered. The query to insert into the database and select from the database works fine; but my problem is I'm not able to count, only receiving a count of 1 at all times. It is not incrementing; my question how do I get the counter to increment rather than just showing 1 at all times. This is what I have so far
protected void btnComplete_Click(object sender, EventArgs e)
{
string id = txtid.Text;
string user = lblUsername.Text;
string date = lblDate.Text;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["TWCL_OPERATIONSConnectionString"].ToString());
//commands identifying the stored procedure
SqlCommand cmd = new SqlCommand("selectId", conn);
SqlCommand cmd1 = new SqlCommand("CreateUserId", con);
// execute the stored procedures
cmd.CommandType = CommandType.StoredProcedure;
cmd1.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#id", id);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
cmd1.Parameters.Add("#id", SqlDbType.NVarChar).Value = barcode);
cmd1.Parameters.Add("#Username", SqlDbType.NVarChar).Value = user;
cmd1.Parameters.Add("#Date", SqlDbType.DateTime).Value = date;
counter = counter + 1;
}
reader.Close();
cmd1.ExecuteNonQuery();
lblCount.Text = counter.ToString();
}
else
{
lblError.Text = barcode + " does not exist!!";
}
}
Before you are asked for stored procedures and before giving you a concrete answer, you should fix some problems in your code
1) use using{} blocks with command and connection to make sure they are disposed.
2) In while loop, you are adding parameters to cmd1. Think what will happen if while loop runs more than 1 time!!
Now, if you want to show max in counter, just get max from database !!
In your cmd object you are sending some ID to stored procedure. It will always return 1 record if id is unique in your table.
So your counter is always 1
Solution
Not modifying much of your code, add count(id) as counter in your storedprocedure query returning result of cmd.
And in the while loop assign that to counter variable.
counter = Convert.ToInteger(reader[“counter”].ToString());
Above is not best solution though. As it will count records for all rows and will reduce performance over time.
For best solution, you need to make another command object that executes a query like select count(id) from YourTableName
This will give you number of records in your table.
Edit
From your comment.
You only want total records after inserting from cmd1.
Just do following:
1) In your storedProcedure for cmd 1, write Select Isnull(count(*),0) from YourTableNameHere
2) In your code, use ExecuteScalar instead of ExecuteNonQuery.
var result = cmd1.ExecuteScalar();
lblCount.Text = result.ToString();
Edit 2
You want to keep track of number of records inserted in current session. Use viewstate or session, depending on your requirement to save counter for session Or only untill user stays on current page.
var recordsAdded = cmd1.ExecuteNonQuery();
if(Session[“counter”] == null)
{
Session[“counter”] = 0;
}
if(recordsAdded>0)
{
Session[“counter”] = Convert.ToInteger(Session[“counter”]) + 1;
}
lblCount.Text = Session[“counter”];
Above will keep track of inserted records in session
Related
I have a code for fetching customer_id and I use a SqlDataReader for reading customer_id from SQL Server. I test witch using breakpoint and step by step debugging and I understand the SqlDataReader condition was not compile and compiler jump straight in to the connection.close line:
string strQuery = "select customer_id from Registration where username=#username and password=#password";
SqlConnection connection1 = DBConnection.getConnection();
connection1.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection1;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
string customer_id = cmd.ExecuteScalar() as string;
connection1.Close();
if (customer_id == null)
{
Messages myMsg = new Messages();
myMsg.CreateMessageAlert("The User does not Registered or your using incorect username or password");
}
else {
Session["customer_id"] = customer_id;
}
Although the issue is not very clear, you can try to revise the code taking following into account:
There is no need to open/close db connection for every sql query in a method. Open it once, execute all queries, close. That will make code clear and faster.
As you take connection from somewhere else, make sure it is closed before you open it (Example: Check if SQL Connection is Open or Closed)
You run 2 queries and in both cases you get only 1 result (select count(*), select customer_id). Why then in first case you do ExecuteScalar() and ExecuteReader() in the other?
The other thought is there is no need to have 2 SqlCommand(), etc if you need to return results of 2 queries. Read about Retrieving Multiple Result Sets using NextResult
And last but not least - it seems you need to check if user is already registered and if true, get his id. Why not do it in one shot? The second query is good for both cases - if user does not exist, query will not return any result, if he does - his id will be returned. Doing this way, you would need only one query and less coding.
UPDATE:
The updated code looks more clear and straightforward, but you didn't get the point of my last comment. If you select count(customer_id) you get a count that you don't need. Why not simply select customer_id and check if it was returned or not?
Example:
//string strQuery = "select count(customer_id) from Registration where username=#username and password=#password";
string strQuery = "select customer_id from Registration where username=#username and password=#password";
SqlConnection connection1 = DBConnection.getConnection();
connection1.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection1;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
//int intRowCount = (int)cmd.ExecuteScalar();
string customer_id = cmd.ExecuteScalar() as string;
//txt1_username.Text = intRowCount.ToString(); <-- What's this?
connection1.Close();
//if (intRowCount == 1)
if (customer_id == null)
{
// user does not exist, because sql returned no rows
... <-- do something here
} else {
Session["customer_id"] = customer_id;
}
UPDATE #2:
To troubleshoot
Make sure txt1_username.Text and txt2_password.Text have expected values. It could be that you reset the Text somewhere and that could be the reason why the query returned no result. Try to hardcode the value in the code, for example,
cmd2.Parameters.AddWithValue("username", "admin");
cmd2.Parameters.AddWithValue("password", "123");
Copy-paste entire sql in Sql Server Management Studio (or other tool) and run it from here to ensure what result it returned.
Make sure you execute it against correct database (maybe you have different databases with same tables where data is different).
This is because your username is no longer the username. It is actually 1 because of the line
int intRowCount = (int) cmd.ExecuteScalar();
txt1_username.Text = intRowCount.ToString(); <-- RED FLAG
So in the inside the If, you are actually running
SELECT customer_id FROM registration WHERE username=1 and password=my_password
Comment line 15 and you should do fine.
updated
string strQuery = "select count(*) from Employee where FullName=#username";
SqlConnection connection = DBConnection.getConnection();
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = strQuery;
cmd.Parameters.AddWithValue("username", txt1_username.Text);
cmd.Parameters.AddWithValue("password", txt2_password.Text);
int intRowCount = (int)cmd.ExecuteScalar();
txt1_username.Text = intRowCount.ToString();
if (intRowCount == 1)
{
string strquery = "select customer_id from Registration where username=#username and password=#password";
SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = connection;
cmd2.CommandText = strquery;
cmd2.Parameters.AddWithValue("username", txt1_username.Text);
cmd2.Parameters.AddWithValue("password", txt2_password.Text);
SqlDataReader reader = cmd2.ExecuteReader();
if (reader.Read())
{
string customerID = reader[0].ToString();
}
}
connection.Close();`
This is complete solution for your issue.
Do not need to open connection everytime. just make sure, connection is being closed once it's used.
I've got a problem for the past few days. I will explain short what i've did.
I have a table created in the database called 'Cart'. This Cart cointains: ClientID, Artical number, and quantity. In the ClientID, a session.sessionID stored. In the Artical just a number like 1012. And in quantity a number like 1 or 3.
What I would like to, is retrieve all the records, with the session.session id of the user.
It does work in the page, but only the first record of the like 4-5 records that are in the cart table is shown. I think i comes due the problem that it looks for this.session.sessionidand when it found one, it doesn't look any further then that.
I've tried to loop through the query where sessions is. But it won't let me loop because it doesn't know for? Even if I loop the whole query outside of it like this:for (int i = 0; i < sessies.Length; i++) It will show more records.. but they are all the first records.. I know that was a stupid try but I can always try..
Looked for all over the internet but couldn't find the solution to this.
Hope to get a response soon from somebody. It would be gratefull.
Used the following code:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["GarageConnectionString"].ToString()))
{
string sessions = this.Session.SessionID;
SqlCommand cmd = new SqlCommand("SELECT * FROM cart where ClientID='" + sessions + "'", cn);
cn.Open();
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
rdr.Read();
TextBox1.Text = rdr[2].ToString();
Response.Write("<br>" + ("Sessie id "+rdr[1].ToString()));
Response.Write("<br>" + ("Artikel nummer "+rdr[2].ToString()));
Response.Write("<br>" + ("Aantal "+rdr[3].ToString()));
cn.Close();
}
SqlDataReader advances to the next record in the set: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.read%28v=vs.110%29.aspx
Call Read() in a loop, like so:
using (SqlConnection cn = newSqlConnection(ConfigurationManager.ConnectionStrings["GarageConnectionString"].ToString()))
{
string sessions = this.Session.SessionID;
SqlCommand cmd = new SqlCommand("SELECT * FROM cart where ClientID='" + sessions + "'", cn);
cn.Open();
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (rdr.Read())
{
TextBox1.Text = rdr[2].ToString();
Response.Write("<br>" + ("Sessie id "+rdr[1].ToString()));
Response.Write("<br>" + ("Artikel nummer "+rdr[2].ToString()));
Response.Write("<br>" + ("Aantal "+rdr[3].ToString()));
}
cn.Close();
}
You should loop through the datareader: ie:
while (rdr .Read())
{
Console.WriteLine("{0}\t{1}", rdr .GetInt32(0),
rdr .GetString(1));
}
Each call to SqlDataReader.Read() gets a single row, unless there are no more rows when it returns false.
So you need to loop to get all rows:
while (rdr.Read()) {
// Use rdr methods to access the values from the current row.
}
Use While Loop- Example
if (rdr .HasRows)
{
while (rdr .Read())
{
Console.WriteLine("{0}\t{1}", rdr .GetInt32(0),
rdr .GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
rdr .Close();
I have this store procedure with out parameter
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `usp_count_rows`(OUT total int)
BEGIN
SELECT COUNT(*)
FROM address_book.persons;
END
I want to use it in asp.net page. I write this code behind:
string commandText = "usp_count_rows";
MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["mySqlString"].ConnectionString);
MySqlCommand cmd = null;
try
{
cmd = new MySqlCommand(commandText, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("total", MySqlDbType.Int32);
cmd.Parameters["total"].Direction = ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
int total = (int)cmd.Parameters["?total"].Value;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Clone();
}
and i got this error message
Specified cast is not valid.
fot the line
int total = (int)cmd.Parameters["?total"].Value;
What should I do to make the code work. And another thing I want ot use the result in aspx page. Something like this: Total number of rows: (result from store procedure). Do you have some suggestions?
This is happening because your SP doesn't return any parameters, just result of the query. And for a stored procedure like this you do not need any parameters - even output ones, so redefine your SP simple as
CREATE DEFINER=`root`#`localhost` PROCEDURE `usp_count_rows`
BEGIN
SELECT COUNT(*)
FROM address_book.persons;
END
Then in you C# get rid of lines (remove them completely):
cmd.Parameters.Add("total", MySqlDbType.Int32);
cmd.Parameters["total"].Direction = ParameterDirection.Output;
and replace these lines:
cmd.ExecuteNonQuery();
int total = (int)cmd.Parameters["?total"].Value;
with this one line:
int total = Convert.ToInt32(cmd.ExecuteScalar());
ExecuteScalar method executes your SP/Query and returns first column of first row of that query (in your case it will be the only column and the only row with the Count(*)).
Oh by the way in your Finally block it should be conn.Close() not conn.Clone(), but I think it's simple a type.
As for displaying results on the ASPX page - there're multiple ways depending on where and how you want to display it. For example you can add a Label control to your page and execute something like:
Label1.Text = "Total number of rows: " + total.ToString();
here,using request.Querystring i find the companyname and job title of particular Job.when user logsin using username in texbix.i want the Companyname,jobtitle and username in the same row of a table.But when i generate my query it inserts the (companyName & jobtitle) in the first row and username in second row.How can i fulfill my task.Some people said,i have to keep the companyname and jobtitle in a variable...then execute.
is it a parfect solution?
if it is,how can i do that?
code:
protected void ButtonApply_Click(object sender, EventArgs e) {
String str = Request.QueryString.Get("JobNo");
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
conn.Open();
string apply = "INSERT INTO Company (CompanyName,JobTitle) select CompanyName,JobTitle from Jobs where JobNo='"+str+"'" ;
SqlCommand insertApply = new SqlCommand(apply, conn);
try {
insertApply.ExecuteScalar();
conn.Close();
Response.Redirect("ApplyJob.aspx?JobNo="+str);
}
in the apply.aspx i have following code:
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
conn.Open();
string apply = "INSERT INTO Company (CandidateInformation) Values (#CandidateInformation)" ;
SqlCommand insertApply = new SqlCommand(apply, conn);
insertApply.Parameters.AddWithValue("#CandidateInformation", TextBoxaun.Text);
insertApply.ExecuteNonQuery();
conn.Close();
Response.Redirect("CompanyInfo.aspx");
Inserting two times will always result in two new rows.
You can do it all in the first insert statement:
string apply = "INSERT INTO Company (CompanyName,JobTitle, CandidateInformation) select
CompanyName,JobTitle, #CandidateInformation from Jobs where JobNo=#JobNo ;
SqlCommand insertApply = new SqlCommand(apply, conn);
insertApply.Parameters.AddWithValue("#CandidateInformation",
TextBoxaun.Text);
insertApply.Parameters.AddWithValue("#JobNo", str);
try
{
insertApply.ExecuteScalar();
conn.Close();
Response.Redirect("CompanyInfo.aspx");
}
Then you won't need the second page.
Use
Update Company Set CandidateInformation = #CandidateInformation where JobNo='"+str+"'" ;
instead of
string apply = "INSERTINTO Company (CandidateInformation) Values
(#CandidateInformation)" ;
If you will use Insert statement again, then it will always create new record in the table.
Update is used to update an already existing record of the table.
I have a grid view which uses SQL to calculate information that I need! I want to put this calculated total into another table in database.
SELECT StaffDetails.StaffID, SUM(HolidayRequests.RequestTotalDays) AS Expr1
FROM HolidayRequests INNER JOIN StaffDetails ON HolidayRequests.Username = StaffDetails.UserName
WHERE (StaffDetails.StaffID = #staffID)
GROUP BY StaffDetails.StaffID, HolidayRequests.ApprovalStatus
HAVING (HolidayRequests.ApprovalStatus = N'approved')
It basically calculates the total number of approved holiday requests for a staff member which is correct. I want this number to then update the HolidayTaken field in another table each time a holiday is approved.
I have tried an update however you cannot use an aggregate in an update as I have found...Any idea how else I can do this..
you could load the executed Query into a "DataReader" or "DataSet" and from there load the information to the new Table.
you could do:
SqlConnection conn = "You connection";
SqlCommand cmd = new SqlCommand(conn);
cmd.CommandText = "YOUR QUERY";
SqlDataReader rdr = cmd.ExecuteReader();
String UpdateQuery;
while (rdr.Read())
{
UpdateQuery = "UPDATE table set col1=#Expr1 WHERE condition"
cmd.Parameters.AddWithValue("#Expr1", rdr["Expr1"].ToString());
//run update query
cmd.CommandText = UpdateQuery;
cmd.ExecuteNonQuery();
return;
}
cmd.Connection.Close();
Try this
UPDATE StaffDetails a
SET a.HolidayTaken = (SELECT SUM(HolidayRequests.RequestTotalDays)
FROM HolidayRequests INNER JOIN StaffDetails b ON HolidayRequests.Username = b.UserName
WHERE (b.StaffID = #staffID)
GROUP BY b.StaffID, HolidayRequests.ApprovalStatus
HAVING (HolidayRequests.ApprovalStatus = N'approved'))
WHERE a.StaffID = #staffID