I am trying to get total number of records when the following query is run:
var cmd =new SqlCommand("SELECT * FROM Issue where BookID = #bid and IssueDate = #idate order by IssueDate desc", conn);
cmd.Parameters.AddWithValue("bid", bookid);
cmd.Parameters.AddWithValue("idate", DateTime.Now);
int val = cmd.ExecuteNonQuery();
There is a record available in the database, but val always return -1.
Problem : You are trying to execute the query which returns the actual records from the table but not the Records count.
Solution : To get the Total Records from the Table, you need to call the Query as below:
Syntax:
SELECT COUNT(*) FROM [TABLENAME];
Note : To Read the records count you can either call ExecuteReader() or ExecuteScalar() methods.
but i would strongly recommned to call ExceuteScalar() when there is only one record/value to read.
EDIT: You don't need order by clause here as order of records will not effect the count value.
Try This:
var cmd =new SqlCommand("SELECT COUNT(*) FROM Issue where BookID = #bid and
IssueDate = #idate");
cmd.Parameters.AddWithValue("bid", bookid);
cmd.Parameters.AddWithValue("idate", DateTime.Now);
int totalRecords = Convert.ToInt32(cmd.ExecuteScalar());
You can either iterate through all records or make another query to count them yourself.
Also, don't forget to wrap your SqlCommand to a using statement because it implements the IDisposable interface.
From MSDN:
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers. For all other types of statements, the return value is -1. If a rollback occurs, the return value is also -1.
So you should use the already proposed COUNT based solutions.
Related
objcon.GetReader(" insert into product(name,price)Values('" + txt_name.Text + "','" + txt_price.Text + "') select scope_identity() ");
if (objcon.dr.Read())
{
var id = objcon.dr[0].ToString();
}
objcon.dr.Close();
I want to store the scope_identity value into a variable. The above code is working. But I am not getting the value in variable id. Can someone please help?
It has been a while since I last worked directly with ADO.Net, so this might not be 100% accurate.
var cmd = new SqlCommand(#"
insert into product(name,price) Values(#name, #price);
select scope_identity();", objCon);
cmd.Parameters.AddWithValue("#name", txt_name.Text);
cmd.Parameters.AddWithValue("#price", Convert.ToInt32(txt_price.Text));
var newId = (int)cmd.ExecuteScalar();
The SqlCommand object is ideal for performing queries that returns nothing, or a single value
ExecuteNonQuery() returns the number of affected rows. F.ex. how many row was actually updated, inserted, or deleted (note: triggers can affect this value)
ExecuteScalar() returns the first column of the first row, in the result, and ignores the rest. It's perfect to retrieving a newly inserted ID or a count, or a sum, etc. The returned type is object, but can be cast to the expected type.
I am using following code to check if record exist.
SqlCommand check_Campaign_Name = new SqlCommand("SELECT * FROM Campaign_Summary WHERE ([Compaign_Name] = #user) ", conn);
check_Campaign_Name.Parameters.AddWithValue("#user", txtBox_LastClick_Campaign.Text);
int CampaignExist = check_Campaign_Name.ExecuteNonQuery();
richTextBox1.Text = CampaignExist.ToString();
But I am always getting -1 in the integer CampaignExist. Don't know where I am doing wrong.
ExecuteNonQuery is not supposed to return the number of rows SELECTED, but the number of rows modified by an INSERT/UPDATE/DELETE command. You should use a SqlDataReader and check with its property HasRows or use an aggregate function like COUNT and ExecuteScalar
(Probably the best choiche if you want to just retrieve the number of rows)
SqlCommand check_Campaign_Name = new SqlCommand("SELECT COUNT(*) FROM Campaign_Summary " +
"WHERE Compaign_Name = #user", conn);
check_Campaign_Name.Parameters.AddWithValue("#user", txtBox_LastClick_Campaign.Text);
int rowCount = Convert.ToInt32(check_Campaign_Name.ExecuteScalar());
However, if you want only to know if the row exists or not, then the COUNT approach is considered less efficient than using the EXISTS statement.
string cmdText = #"IF EXISTS (SELECT Compaign_Name FROM Campaign_Summary
WHERE Compaign_Name = #user)
SELECT 1 ELSE SELECT O";
SqlCommand check_Campaign_Name = new SqlCommand(cmdText, conn);
int rowExists = Convert.ToInt32(check_Campaign_Name.ExecuteScalar());
This second approach just allows to know if there are rows that fits the WHERE statement or not.
So it is not exactly like COUNT(*) where you get the exact number of rows.
Use executescalar method and count on query
SqlCommand check_Campaign_Name = new SqlCommand("SELECT COUNT(1) FROM Campaign_Summary WHERE ([Compaign_Name] = #user) ", conn);
check_Campaign_Name.Parameters.AddWithValue("#user", txtBox_LastClick_Campaign.Text);
int CampaignExist = Convert.ToInt32(check_Campaign_Name.ExecuteScalar());
richTextBox1.Text = CampaignExist.ToString();
From MSDN,
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers. For all other types of statements, the return value is -1. If a rollback occurs, the return value is also -1.
As your query is a SELECT and not one of the mentioned UPDATE, INSERT or DELETEs, it will always return -1.
Try with Execute scalar MSDN
int CampaignExist = Convert.ToInt(check_Campaign_Name.ExecuteScalar());
SqlCommand check_Campaign_Name = new SqlCommand("SELECT COUNT(1) FROM Campaign_Summary WHERE ([Compaign_Name] = #user) ", conn);
check_Campaign_Name.Parameters.AddWithValue("#user", txtBox_LastClick_Campaign.Text);
int CampaignExist = Convert.ToInt32(check_Campaign_Name.ExecuteScalar());
richTextBox1.Text = CampaignExist.ToString();
ExecuteNonQuery is not used to retrieve results
You can use one of the following methods:
SqlCommand.ExecuteScalar (I would prefer this)
DataAdapter.Fill
Query always return -1 don't know why. Will someone please explain. Value of count always remains -1.
string query = "SELECT COUNT(*) AS Emails FROM users";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#email", email);
try
{
connection.Open();
count = command.ExecuteNonQuery();
if (count > 0)
return "Something Wrong1";
}
catch
{
return "Something Wrong2";
}
return count + "Every thing ok";
}
That is because ExecuteNonQuery does not return the result of the query, it just executes it on the SQL server. The return value is the number of rows affected by your statement, -1 when the statement does not affect any rows. ExecuteNonQuery (as the name implies) is not intended for returning query results, but rather for running a statement that changes data (such as INSERT, DELETE, UPDATE). The docs state:
For UPDATE, INSERT, and DELETE statements, the return value is the
number of rows affected by the command. (...) For all other types of
statements, the return value is -1. If a rollback occurs, the return
value is also -1.
You could use:
count = (int)command.ExecuteScalar();
To get the count you are looking for. There is also an example in the docs for ExecuteScalar.
You need ExecuteScalar not ExecuteNonQuery to retrieve the count value.
I think that perhaps what you mean is for your SQL statement to be:
SELECT COUNT(*) FROM users WHERE Email = #email
Besides that, you must use the ExecuteScalar method to retrieve the count.
I'm no C# expert, but that command.ExecuteNonQuery() doesn't seem right ... it's a query after all!
I've got a function that stores temporary information generated for every user authenticated in the system. This 'session ID' is a string stored in a Sessions table, along the original ID of the user which authenticated and was given said session identifier.
The function to remove/deauthenticate/invalidate an existing session first checks if the user exists through another method implemented as follows:
int userId = 0;
SqlCeCommand cmd = new SqlCeCommand();
SqlCeParameterCollection sqlParams = cmd.Parameters;
sqlParams.AddWithValue("#User", userName);
cmd.Connection = this.conn;
cmd.CommandText = "SELECT Id FROM Users WHERE (Username = #User)";
userId = (int) cmd.ExecuteScalar()
cmd.Dispose();
Afterwards it tries to find an existing session for that user, which is to be removed (via a different method again):
SqlCeCommand cmd = new SqlCeCommand();
SqlCeParameterCollection sqlParams = cmd.Parameters;
sqlParams.AddWithValue("#SID", mysession);
sqlParams.AddWithValue("#UID", myuserid);
cmd.Connection = this.Connection;
cmd.CommandText = "SELECT Id FROM UserSessions WHERE (SessionID = #SID) AND (User_Id = #UID)";
int foo = cmd.ExecuteNonQuery();
...which fails. No exception is raised unfortunately. So I added an insecure equivalent using a non parametrized query string:
cmd.CommandText = String.Format("SELECT Id FROM UserSessions WHERE (SessionID = '{0}') AND (User_Id = {1})", mysession, myuserid);
cmd.Prepare();
int bar = cmd.ExecuteNonQuery();
Added a breakpoint, paused, copy pasted the query into the Visual Studio Query tool and voila, it indeed worked. But after continuing, that query in the code failed as well. I'm unable to find the culprit of this annoying issue since no exception is raised and everything seems correct. The data exists, the parameters are provided in proper types (string and int) and I'm out of things to check. The connection is open and so forth.
Any clues from anyone around? Thanks!
Update: Mea culpa, missed the fact that the function used ExecuteScalar until I modified it for testing. It does use ExecuteScalar and returns null, just in case.
You're using ExecuteNonQuery:
int foo = cmd.ExecuteNonQuery();
... but you're clearly trying to execute a query (a SELECT)! Use ExecuteScalar again, as you did in the first code, or ExecuteReader and look through the results appropriately. If you stick with ExecuteScalar, you should first check whether the result is null to indicate no results.
ExecuteNonQuery returns the number of rows affected by an UPDATE/INSERT/DELETE command - which is what it's intended for. I suspect it's returning -1 for you, as documented:
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers. For all other types of statements, the return value is -1. If a rollback occurs, the return value is also -1.
(Emphasis mine.)
Use set [] to avoid ambiguity with database keyword.
cmd.CommandText = "SELECT [Id] FROM [Users] WHERE ([Username] = #User)";
and use ExecuteScalar() or ExecureReader() method when working with SELECT statements.
I think nothing's wrong with the connection because when I open it, it does not throw any error. So I guess the error is when I'm executing a command. This is my code:
OleDbCommand cmd = new OleDbCommand("SELECT * FROM cars", conn);
cmd.CommandType = CommandType.Text;
int numbers = cmd.ExecuteNonQuery();
I tried using a message box to display the value of numbers but the result is always 0. The table cars contains 5 records. So why am I not getting the correct results?..
To the anonymous downvoter, the key part of the OP:
I tried using a message box to display the value of numbers but the
result is always 0. The table cars contains 5 records. So why am I not
getting the correct results?..
The OP is obviously trying to get a count of records in the table (a scalar aggregate) and not all of the table data.
My answer:
That's because your query is returning a table and not a scalar value and you're calling the incorrect function. Your query should be should be:
"SELECT COUNT(*) FROM cars"
And ExecuteNonQuery doesn't actually expect any results to be returned. (You usually run insert, update and delete operations with ExecuteNonQuery.) You should be using ExecuteScalar which expects a single-valued result such as count(*).
All together now:
OleDbCommand cmd = new OleDbCommand("SELECT count(*) FROM cars", conn);
cmd.CommandType = CommandType.Text;
int numbers = cmd.ExecuteScalar();
Try using ExecuteScalar that should give you the count. ExecuteNonQuery doesn't return the results from your query. The return your looking at indicates how many rows were affected by your statement, in your case zero.
ExecuteNonQuery as the name tells you does not make a query. it is normally used for inserts or updates and returns the number of affected records. for the query you provided you should use ExecuteReader or a DataAdapter and its Fill method to fill a datatable.
Because you are executing a query, and ExecuteNonQuery returns the number of rows effected, which when you select is always 0 since you aren't changing anything (ie. INSERT,UPDATE or DELETE)
ExecuteNonQuery only returns the number of rows affected for UPDATE, DELETE or INSERT operations. For the number of rows in the SELECT statement, try:
OleDbCommand cmd = new OleDbCommand("SELECT * FROM cars", conn);
OleDbDataReader reader = cmd.ExecuteReader();
int numbers = 0;
while (reader.Read())
{
//// other Reader-related operations here...
numbers++;
}