Executenonquery have -1 when i execute a statement - c#

I am trying to fetch rows from a table and insert them into another table. For that I have written this simple code but I am not able to figure out what is the issue.
As you can see I have used ExecuteNonQuery after executing my statement and then used messagebox to see the output but the output in message box is -1
for (int i = 1; i <= 10; i++)
{
SqlCommand cmd = new SqlCommand("Select exp_date from tbl_expences where exp_id='" + i + "'", con);
int j = cmd.ExecuteNonQuery();
MessageBox.Show(Convert.ToString(j));
if (j > 1)
{
string date = cmd.ExecuteScalar().ToString();
MessageBox.Show(date);
SqlCommand cmd1 = new SqlCommand("update other_expensive set exp_date='" + date + "' where exp_id='" + i + "'", con);
}
}

ExecuteNonQuery() is used for INSERT, UPDATE or DELETE. Use ExecuteReader() if you want to use SELECT.

Why would you run 20 (possibly 30, depending on what else happens in this code) statements for this?
From the documentation of ExecuteNonQuery:
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 added)
Why not just:
update oe set exp_date=e.exp_date
from
other_expensive oe
inner join
tbl_expense e
on
oe.exp_id = e.exp_id
where
e.exp_id between 1 and 10
Which will do all of the updates in parallel, using one query, and avoid the loop, and the "step-by-step" approach you seem to be trying to use.

Related

Execute non query returns negetive one(-1) but still inserts [duplicate]

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();
}
}

why com.ExecuteNonQuery() return -1 Always . in all cases

com.ExecuteNonQuery() always returns -1 - in all cases.
Why is it always = -1 ?
SqlConnection conn = newSqlConnection(ConfigurationManager.ConnectionStrings["UsersConnectionString"].ConnectionString);
conn.Open();
string insertquery = " select UserName from Users where Username='" + CurrentName + "' ";
SqlCommand com = new SqlCommand(insertquery, conn);
com.ExecuteNonQuery();
int ii = com.ExecuteNonQuery();
Response.Write(ii);
It's because you're using it with a SELECT SQL command.
From the documentation for SqlCommand.ExecuteNonQuery (emphasis mine):
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.
It's not clear what you're trying to achieve, but this basically isn't the way to do it.
You are using a select Query so the result will always be -1.
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.
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["UsersConnectionString"].ConnectionString);
conn.Open();
string query = "select UserName from Users where lower(Username)=lower('" + CurrentName + "')";
SqlCommand com = new SqlCommand(query, conn);
string result = "";
result = com.ExecuteScalar() == null ? "" : com.ExecuteScalar().ToString();
conn.Close();
Response.Write(result);
try out this

c# alter table name add column

Command executed successfully look at here,..
string strConn = "Data Source=USER\\SQLExpress; Initial Catalog=empdata; Integrated Security=true";
SqlConnection conn = new SqlConnection(strConn);
conn.Open();
SqlCommand sqlCmd = new SqlCommand("alter table empreg ADD '"+ this.comboBox1.Text +"' varchar(50)", conn);
int res=sqlCmd.ExecuteNonQuery();
if (res == 1)
{ MessageBox.Show("New column created"); }
else
{ MessageBox.Show("sorry unable to create"); }
But it goes to 2nd part of if "sorry unable to create" result and the thing is that in SQL studio we can see that column created.
How is it possible ???
your result is the amount of affected rows, 1 doesn't mean you got an error.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery%28v=vs.110%29.aspx
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.
From the MSDN page:
"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 need to handle res ==-1, not res ==1
from http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery(v=vs.110).aspx
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.
SqlCommand.ExecuteNonQuery => "Executes a Transact-SQL statement against the connection and returns the number of rows affected."
It will always return number of rows altered or not
Read more SqlCommand.ExecuteNonQuery
qlCommand sqlCmd = new SqlCommand("alter table empreg ADD '"+ this.comboBox1.Text +"' varchar(50)", conn);
correct
qlCommand sqlCmd = new SqlCommand("alter table empreg ADD "+this.comboBox1.Text+" varchar(50)", conn);
and dont need
if (res == 1)
{ MessageBox.Show("New column created"); }
else
{ MessageBox.Show("sorry unable to create"); }

ExecuteNonQuery() Returns unexpected number of rows affected C#

Here's my code
// SqlCommand query = new SqlCommand("INSERT INTO devis (idProposition, identreprise, tauxHoraire, fraisGenerauxMO, fraisGenerauxPiece, beneficeEtAleas, idStatut, prixUnitaireVenteMO ) VALUES(#idproposition, #identreprise, #tauxHoraire, #fraisGenerauxMO, #fraisGenerauxPiece, #beneficeEtAleas, 1, #prixUnitaireVenteMO) ", Tools.GetConnection());
SqlCommand query = new SqlCommand("INSERT INTO devis (idProposition, identreprise, tauxHoraire, fraisGenerauxMO, fraisGenerauxPiece, beneficeEtAleas, idStatut, prixUnitaireVenteMO, alerteEntrepriseEnvoyee,fraisDeplacement ) VALUES(1051, 85, 20, 2, 2, 2.2, 1, 88,0,-1) ", Tools.GetConnection());
//query.Parameters.AddWithValue("idproposition", this.ID);
//query.Parameters.AddWithValue("identreprise", competitor.ID);
//query.Parameters.AddWithValue("tauxHoraire", competitor.CoefTauxHoraire);
//query.Parameters.AddWithValue("fraisGenerauxMO", competitor.CoefFraisGenerauxMO);
//query.Parameters.AddWithValue("fraisGenerauxPiece", competitor.CoefFraisGenerauxPiece);
//query.Parameters.AddWithValue("beneficeEtAleas", competitor.CoefBeneficeEtAleas);
//query.Parameters.AddWithValue("prixUnitaireVenteMO", Math.Round(competitor.CoefTauxHoraire * competitor.CoefFraisGenerauxMO * competitor.CoefBeneficeEtAleas, 2));
bool insertOK = (query.ExecuteNonQuery() == 1);
if (insertOK)
{
// DO SOMETHING
}
insertOk is false but in the database the row is inserted with all the information that I specified
I rebuilt the query manually to see if the problem came from the query.Parameters, it inserts without error again into the database but insertOk is still false! I even added two other fields which aren't supposed to be null but the activity is the same in both cases
any ideas?
ExecuteNonQuery it claims to return The number of rows affected.. This is incorrect, as there is no way for the client to know the number of rows affected. The documentation incorrectly assumes that the engine will report the number of rows affected, but that is subject to the session SET NOCOUNT state. Do not write code that assumes the NOCOUNT is always on. If you need to know the number of rows affected use the OUTPUT clause. Relying on the ##ROWCOUNT or the SET NOCOUNT state is subject to many many corner cases where the value is incorrect from one point of view or another.
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.
ExecuteNonQuery method returns System.Int32
Executes a Transact-SQL statement against the connection and returns
the number of rows affected.
Return Value
Type: System.Int32
The number of rows affected.
Since your query.ExecuteNonQuery() returns 2, it is too obvious 2 == 1 returns false.
Your query will be;
bool insertOK = (2 == 1);
DEMO.
Try using SqlDataAdapter such that :
SqlDataAdapter Adabter = new SqlDataAdapter();
Adabter.InsertCommand = new SqlCommand("INSERT INTO devis values(#idProposition, #identreprise), Tools.GetConnection());
Adabter.InsertCommand.Parameters.Add("#idproposition",SqlDbType.Int).Value = yorID;
Adabter.InsertCommand.Parameters.Add("#identreprise", SqlDbType.Int).Value = yorID;
Tools.OpenConnection();
int result = Adabter.InsertCommand.ExecuteNonQuery();
Tools.CloseConnection();
if( result > 0 )
{
MessageBox.Show("Information Added");
}else
{
MessageBox.Show("Error");
}
Same issue here with an UPDATE query. In my case I had to add "set nocount off" to the SQL. Example code:
string sql =
$#"set nocount off;update PRODUCT_PLAN
set WORKING_STATUS = 'P',
user_id = #USER_ID
where workorder_base_id = #BASE_ID
";
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType =CommandType.Text;
cmd.Parameters.AddWithValue("#USER_ID", opl.USER_ID);
cmd.Parameters.AddWithValue("#BASE_ID", opl.WORKORDER_BASE_ID);
cmd.CommandText = sql;
// Nr of rows updated in retval
int retval = cmd.ExecuteNonQuery();

C# - SELECT Query number of rows affected is always -1

I have this code and it always returns -1.I have three tables (a picture is more suggestive ):
I want to see if the row is already in the ReservationDetails table, and if it's not to insert it.
try
{
SqlConnection conn = new SqlConnection...
SqlCommand slct = new SqlCommand("SELECT * FROM ReservationDetails WHERE rID=#rID AND RNumber=#RNumber", conn);
slct.Parameters.AddWithValue("#rID", (int)comboBox1.SelectedValue);
slct.Parameters.AddWithValue("#RNumber", dataGridView1.SelectedRows[0].Cells[0].Value);
int noRows;//counts if we already have the entry in the table
conn.Open();
noRows = slct.ExecuteNonQuery();
conn.Close();
MessageBox.Show("The result of select="+noRows);
if (noRows ==0) //we can insert the new row
Have you read the documentation of SqlCommand.ExecuteNonQuery?
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.
And your query is SELECT.
You should
1) Change your TSQL to
SELECT COUNT(*) FROM ReservationDetails WHERE ...
(better still, use IF EXISTS ...)
2) and use ExecuteScalar():
noRows = (int) slct.ExecuteScalar();
Also: you will need to use a transaction (or some other atomic technique), or else someone could insert a row in-between you testing and trying to insert it...
All that said, it would be better to create a stored procedure that given your parameters, atomically tests and inserts into the table, returning 1 if successful, or 0 if the row already existed.
It is better to do it in a single query so that you do not need to request server two times.
Create a procedure like this and call it from the code.
IF EXISTS (SELECT 1 from ReservationDetails WHERE rID=#rID AND RNumber=#RNumber)
BEGIN
insert into ReservationDetails values(#rID,#RNumber)
END
As per Microsoft:
You can use the ExecuteNonQuery to perform catalog operations (for example, querying the structure of a database or creating database objects such as tables), or to change the data in a database without using a DataSet by executing UPDATE, INSERT, or DELETE statements.
What you may need, instead of ExecuteNonQuery is ExecuteScalar and put the COUNT in your select query.
i.e.
SqlCommand slct = new SqlCommand("SELECT COUNT(*) FROM ReservationDetails WHERE rID=#rID AND RNumber=#RNumber", conn);
Also, try to make use of the using statement in C#, so you don't need to worry about closing the connection manually, even if things fail.
i.e.
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
try
{
conn.Open();
newProdID = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
//Do stuff
}
}
see:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
#nickNatra
When ever you use
Select command
It will return you values. Which can be either used by
DataSet or SqlDataReader
But
command.ExecuteNonQuery()
is used only when you are using
Insert , Update , Delete where the Rows are getting effected in your table
Yes, If you do want to know how much records are there in your query.
You can perform
a) Modify your query "select count(*) from table"
where you will only get one value ie. Number of Rows.
b) Using this query perform command. ExecuteScalar() which will return only First row and first column which is the Row Count
Hence this satisfy's your requirement.
Cheers!!

Categories

Resources