c# ExecuteNonQuery always returns Zero - c#

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++;
}

Related

How to store query results in a variable

I am trying to store the results of a MySql query into a variable so that I can output the result as part of a sentence.
The query is as follows:
MySqlCommand command = conn.CreateCommand();
command.CommandText = "select count(*) from customerdetails";
conn.Open();
command.ExecuteNonQuery();
I have read other forums and they have spoken about a method using "addwithvalue" however this hasnt been successful when I have used it, and the query result hasn't been outputted.
ExecuteNonQuery() is used for doing any insert, updates or delete operations only.
ExecuteNonQuery :
Executes a Transact-SQL statement against the connection and returns the number of rows affected.
For selecting data you need to use ExecuteReader() which will read the data from the table in a sequential way.
ExecuteReader :
Sends the CommandText to the Connection and builds a SqlDataReader.
So you will have to write it like:
MySqlDataReader reader = command.ExecuteReader();
int rowsCount = 0;
if(reader.Read())
{
rowsCount = reader.GetInt32(0);
}

What exactly does cmd.ExecuteNonQuery() do in my program

string connection = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=D:\\it101\\LoginForm\\App_Data\\registration.mdb";
string query = "INSERT INTO [registration] ([UserID] , [Name] , [Contact_no] , [City]) values (123, 'abc' ,12345, 'pqr')";
OleDbConnection con = new OleDbConnection(connection);
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
And what if i do not write cmd.ExecuteNonQuery() at the end of my program?
And if the query needs to be executed why is it written executeNonquery() instead of executeQuery()?
if we want to deal with database two things will happen i.e; Modifying,Retrieving
Modifying:
In Modifying Section,we have Insert, Delete ,Update,...queries.so for this we need to use ExecuteNonQuery command.why because we are not querying a database, we are modifying.
syntax:
cmd.ExecuteNonQuery Method
Retrieving:
In this we query a database by using Select Statement.For this we use ExecuteReader(),ExecuteScalar()
If select Query return more than one record.we need to use ExecuteReader()
If select Query return only one record.we need to use ExecuteScalar()
syntax:
cmd.ExecuteReader() Method
cmd.ExecuteScalar() Method
The above statements(ExecuteReader(),ExecuteScalar(),SqlCommand.ExecuteNonQuery()) are used to execute command statement which you give in SqlCommand.If you dont use, your command not be executed.
ExecuteNonQuery executes a query that is not expected to produce any results (e.g. an UPDATE, or INSERT).
ExecuteQuery executes a query that is supposed to produce a result (i.e. a SELECT).
If you do not write ExecuteNonQuery at the end, your query won't be executed.
SqlCommand.ExecuteNonQuery Method
Executes statement against the connection and returns the number of rows affected.
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command.
executeQuery Method
Runs the given SQL statement and returns a single SQLServerResultSet object.
If you want to execute your query you should use ExecuteNonQuery

Query is always returning -1 in C#

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

How to know if a query succeeded?

How can I know if the following INSERT query succeeded?
MySqlConnection connection = new MySqlConnection(ConnectionString);
connection.Open();
MySqlCommand command = new MySqlCommand("INSERT INTO People (PersonName, dateAdded) VALUES (?name, NOW())", connection);
command.Parameters.Add(new MySqlParameter("name", Name));
MySqlDataReader Reader = command.ExecuteReader();
I tried running Reader.Read() but only an empty string is returned. Thanks.
You instead use ExecuteNonQuery:
int affectedRows = command.ExecuteNonQuery();
if (affectedRows <= 0)
{
// Houston, we have a problem.
}
Keep in mind if you have triggers on the data, it may not reflect the actual number of rows you attempted to INSERT:
You can use ExecuteNonQuery to perform any type of database operation, however any resultsets returned will not be available. Any output parameters used in calling a stored procedure will be populated with data and can be retrieved after execution is complete. 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.
In general, however, you will receive a MySqlException if your query encounters an error.
Don't use ExecuteReader if you're doing an INSERT, UPDATE or DELETE. Use ExecuteNonQuery instead, it'll return the number of affected rows.
See http://dev.mysql.com/doc/refman/5.6/en/connector-net-tutorials-intro.html#connector-net-tutorials-sql-command
Only use the SqlDataReader when you're queryng the data base, the SqlDataReader is a fast forward-only pointer, so only is recommended for Querying, use the ExecuteNonQuery() method of the SqlCommand, for example as the next code:
using (SqlConnection conn = new SqlConnection("[QueryString]")) {
using (SqlCommand cmd = new SqlCommand("SQL Command",conn)) {
//here you return the number of affected rows
int a = cmd.ExecuteNonQuery();
}
}
I hope, this could help you.
An exception will be thrown if it fails. The exception object will typically contain information about what went wrong (e.g. "primary key violation" etc...).
Also, use ExecuteNonQuery for INSERT, UPDATE or DELETE. The returned value will contain the number of affected rows.

Proper SQL query command with SQL Compact is failing

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.

Categories