Query is always returning -1 in C# - 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

Related

How to read 1 record from a sql server database into a c# textbox?

I want to do this (on Form3):
sqlcon.Open();
string selectQuery = "SELECT * FROM InvoiceTable where id = #id";
SqlCommand sqlcmd = new SqlCommand(selectQuery, sqlcon);
sqldr = sqlcmd.ExecuteReader();
while(sqldr.Read())
{
textbox1 = Max value of TotalCostColumn.value
or
textbox1 = Latest value of TotalCostColumn.value
or
textbox1 = 2nd row of TotalCostColumn.value
}
Im not having any datagridview on this form. I do have a datagridview on Form1 which is the actual invoice form. Form3 is the confrimation form which lets the user confirm how much customer should pay eventually. I want the TotalCostColumn's value from my database to be transfered in the related textbox in Form3.
textbox1 = Max value of TotalCostColumn.value
If that's your requirement then why not build the query as per like
SELECT max(TotalCostColumn) FROM InvoiceTable where id = #id
And then instead of using ExecuteReader() you should call ExecuteScalar() which would return a single value
This is how you'd get the Max value with ExecuteScalar:
string selectQuery = "SELECT MAX(TotalCostColumn) FROM InvoiceTable where id = #id";
var sqlcmd = new SqlCommand(selectQuery, sqlcon);
var result = sqlcmd.ExecuteScalar();
return int.Parse(result.ToString());
MAX will ensure you only get one row from the table.
To get the latest value, you'd have to sort the table (I assume there's a transaction date) and add TOP 1 to get only the first row. (Although ExecuteScalar will ignore everything except the first field of the top row but there's no point returning data you don't need)
There are two ways to get the second row. One is to use a datareader and skip over the first row. The other is with SQL:
SELECT TOP 1 FROM
(
SELECT TOP 2 TotalCost FROM InvoiceTable where id = #id ORDER BY TotalCost DESC
) ORDER BY TotalCost ASC
Here the inner query gets two rows of data sorted with the largest item first, and the outer query picks the lower value of the two.
You need to write a stored procedure which accepts the value of the id
stored procedure is defined as follows
create proc selectmax(#id int)
as begin
select max(TotalCostColumn) FROM InvoiceTable where id = #id
end
and call it as below using Disconnected Model so sqlcon.open() is not Required
SqlCommand sqlcmd = new SqlCommand(selectmax, sqlcon);
sqlcmd.CommandType=CommandType.StoredProcedure
SqlDataAdapter adapter= new SqlDataAdapter(sqlcmd);
DataSet value=new DataSet();
adapter.Fill(value);
This is the implementation using Ado.net Disconnected Model

ExecuteNonQuery returning -1 when using sql COUNT despite the query string

For some reason, ExecuteNonQuery() in C# returns -1, though when I run a query separately, the value returns the actual value needed.
For Example:
try
{
var connString ="Data Source=ServerName;InitialCatalog=DatabaseName;Integrated Security=true;"
SqlConnection conn = new SqlConnection(connString);
SqlCommand someCmd = new SqlCommand("SELECT COUNT(*) FROM SomeTable");
someCmd.Connection = conn;
conn.Open();
var theCount = cmd.ExecuteNonQuery();
conn.Close();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
When the command is executed it returns -1. Though if run the query separately,
SELECT COUNT(*) FROM SomeTable;
Column returns one row with a count of 4 if that table being queried has 4 rows.
Based on 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.
You want to return the number of rows affected by the command and save it to an int variable but since the type of statement is select so it returns -1.
Solution: If you want to get the number of rows affected by the SELECT command and save it to an int variable you can use ExecuteScalar.
var theCount = (int)cmd.ExecuteScalar();
You can use Ef core with Ado.net like this example
var context = new SampleDbContext();
using (var connection = context.Database.GetDbConnection())
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT COUNT(*) FROM SomeTable";
var result = command.ExecuteScalar().ToString();
}
}

Getting Total number of records in c#

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.

c# ExecuteNonQuery always returns Zero

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

How can I know if such value exists in database? (ADO.NET)

For example, I have a table, and there is a column named 'Tags'. I want to know if value 'programming' exists in this column. How can I do this in ADO.NET?
I did this: OleDbCommand cmd = new OleDbCommand("SELECT * FROM table1 WHERE Tags='programming'", conn);
OleDbDataReader = cmd.ExecuteReader();
What should I do next?
use SELECT COUNT(*) and check the results.
(and use ExecuteScalar)
(assuming you know how to set the connection and use it)
SELECT TOP 1 1
FROM table1
WHERE Tags='programming'
better version, it is a good practice to use parameters instead of string concatenation, see sql injection
OleDbCommand cmd = new OleDbCommand("SELECT TOP 1 1
FROM table1 WHERE Tags=?", conn);
cmd.Parameters.Add("#p1", OleDbType.VarChar).Value = "Programming";
OleDbDataReader rdr = cmd.ExecuteReader();
if(rdr.Read())
// record exists
else
//Not exists
You should do two things:
If you are just checking the presence of a tag called Programming, you should change your query to return a COUNT instead of returning all rows.
SELECT TOP 1 Column1 FROM Table1 WHERE Tags = 'Programming'
You should check the returned set in the reader to see if there are any rows. If there are, then it means that the tag exists.

Categories