queryShelf = "SELECT * FROM shelftable WHERE ShelfId= #ShelfId";
//Create Mysql Command
MySqlCommand cmd = new MySqlCommand(queryShelf, connection);
cmd.Parameters.Add(new MySqlParameter("#ShelfId", MySqlDbType.VarChar)).Value = MainWindow.shelfIds[i];
//ExecuteScalar will return one value
int Count = int.Parse(cmd.ExecuteScalar() + "");
ExecuteScalar is used to return a single value, you are selecting complete records. So normally you use ExecuteReader and use Read to get all records.
But actually you can use ExecuteScalar with SELECT *. What happens is that the first column of the first row in the result set is returned, or a null reference if the result set is empty.
Since you get NULL it seems that the filter doesn't return a record.
Since you want a count you could change your query to:
queryShelf = "SELECT COUNT(*) FROM shelftable WHERE ShelfId= #ShelfId";
// ...
int Count = (int) cmd.ExecuteScalar();
Now you never get null but the count of records, 0 if no record exists with this ShelfId.
Related
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();
}
}
I'm trying to get the last row of a table using C# but it doesn't seem to be working, this is my code:
MySqlConnection cnnGetID = new MySqlConnection(Global.connectionString);
cmd = "SELECT ContactID FROM Contacten ORDER BY ContactID DESC LIMIT 1";
MySqlCommand cmdGetID = new MySqlCommand(cmd, cnnGetID);
cnnGetID.Open();
string contactID = cmdGetID.ExecuteNonQuery().ToString();
MessageBox.Show(contactID);
cnnGetID.Close();
The value this returns is -1 while it should be returning 59.
The strange thing is is that when I run this command in phpmyadmin I DO get 59.
Any ideas on why C# is not returning the correct value but phpmyadmin is?
EDIT: problem solved, should've uses ExecuteScalar(). Looks like I've been staring at my monitor for a bit too long...
You need to use ExecuteScalar instead of ExecuteNonQuery.
MySqlConnection cnnGetID = new MySqlConnection(Global.connectionString);
cmd = "SELECT ContactID FROM Contacten ORDER BY ContactID DESC LIMIT 1";
MySqlCommand cmdGetID = new MySqlCommand(cmd, cnnGetID);
cnnGetID.Open();
string contactID = cmdGetID.ExecuteScalar().ToString();
MessageBox.Show(contactID);
cnnGetID.Close();
This should resolve your issue.
The value this returns is -1 while it should be returning 59.
No, it's behaving exactly as documented by IDbCommand.ExecuteNonQuery:
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.
You're using a SELECT statement - a query. So instead of executing ExecuteNonQuery, you should be using ExecuteQuery and iterating over the results, or ExecuteScalar, given that you know you'll have a single result:
string contactID = cmdGetID.ExecuteScalar().ToString();
you should use ExecuteScalar because you are returning value ExecuteNonQuery returns the number of rows affected by update delete or insert opeation
you can check this for more info
ExecuteNonQuery
Returns the number of rows affected.
ExecuteScalar
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored.
for more information you can check this The MySqlCommand Object
you can use query like this
MySqlConnection cnnGetID = new MySqlConnection(Global.connectionString);
cmd = "SELECT TOP 1 ContactID FROM Contacten ORDER BY ContactID";
MySqlCommand cmdGetID = new MySqlCommand(cmd, cnnGetID);
cnnGetID.Open();
string contactID = cmdGetID.ExecuteNonQuery().ToString();
MessageBox.Show(contactID);
cnnGetID.Close();
I am trying to get the return count of a query. In my case it always be either 0 or 1. I am inserting an customer into my database, I am whether or not they exist already, if they do I throw an exception, if not I insert. This is what I have:
string selectQuery = "select ([Cust_Num]) from [TBL_Customer] where [Cust_Num] = '" + myTable.Rows[i][custNum] + "'";
SqlCommand sqlCmdSelect = new SqlCommand(selectQuery, sqlConn);
sqlCmdSelect.Connection.Open();
sqlCmdSelect.ExecuteNonQuery();
//checks if query returned anything
int queryCount = Convert.ToInt32(sqlCmdSelect.ExecuteScalar());
sqlCmdSelect.Connection.Close();
Right now, queryCount returns 0 if it doesn't exist in my table. But it returns the customer number if it does exist. So instead of returning 1 it returns 123456 which is the customers number.....
Does anyone know why this is happening?
Instead use count aggregate
select count(Cust_Num) from [TBL_Customer] where [Cust_Num] = ..
for the given cust_num Count aggregate will count how many times cust_num is present. If cust_num exists it will return the count else 0
or even 1 as hardcoded value
select 1 from [TBL_Customer] where [Cust_Num] =..
here if cust_num exists then it will return 1 else nothing will be returned
A few points here.
Why you are using ExecuteNonQuery and ExecuteScalar in your code ? If you just need the count the above answer given by #NoDisplayName is perfect.
Example: This example will return you the count of employees with the last anme Coleridge.
SqlCommand Cmd = new SqlCommand("SELECT COUNT(1) FROM Employee WHERE LastName='Coleridge'");
int result = Convert.ToInt32(Cmd.ExecuteSaclar());
I have a problem with the value returned from SqlCommand, I have this code:
string sqlSelect = "Select TOP 1 Quotation.SentToSupp as SentToSupp FROM Quotation JOIN Notifications ON Quotation.QuotationId = QuotationID ";
SqlCommand Comm = new SqlCommand(sqlSelect, this.Connection);
sqlSelect query selects the first DateTime value. When I call to SqlCommand I want to get this value (just one value). I add the query and my connection fine.
But I don't know how to get my DateTime value... Must to use something like ExecuteReader?
Thank you in advance!!
ExecuteReader works but more objects and more code are required - (An SqlDataReader, call to Read and Extract value). Instead you could simply use the ExecuteScalar method of the SqlCommand object (It returns just the first column of the first row of the resultset)
string sqlSelect = "Select TOP 1 Quotation.SentToSupp as SentToSupp FROM ....";
SqlCommand Comm = new SqlCommand(sqlSelect, this.Connection);
object result = Comm.ExecuteScalar();
if(result != null)
DateTime dtResult = Convert.ToDateTime(result);
Just pay attention to the fact that ExecuteScalar could return a null value if, for some reason, there is no record in the result returned
Use SqlCommand.ExecuteScalar method - Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.
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();