C# MySQL Order By Returns -1 - c#

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

Related

SQL execute scalar returning NULL

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.

SqlCommand read one value

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.

Return last inserted ID without using a second query

I'm working on an ASP.NET project (C#) with SQL Server 2008.
When I insert a row into a table in the database, I would like to get the last inserted ID, which is the table's IDENTITY (Auto Incremented).
I do not wish to use another query, and do something like...
SELECT MAX(ID) FROM USERS;
Because - even though it's only one query - it feels lame...
When I insert something I usually use ExecuteNonQuery(), which returns the number of affected rows.
int y = Command.ExecuteNonQuery();
Isn't there a way to return the last inserted ID without using another query?
Most folks do this in the following way:
INSERT dbo.Users(Username)
VALUES('my new name');
SELECT NewID = SCOPE_IDENTITY();
(Or instead of a query, assigning that to a variable.)
So it's not really two queries against the table...
However there is also the following way:
INSERT dbo.Users(Username)
OUTPUT inserted.ID
VALUES('my new name');
You won't really be able to retrieve this with ExecuteNonQuery, though.
You can return the id as an output parameter from the stored procedure, e.g. #userId int output
Then, after the insert, SET #userId = scope_identity()
even though it's only one query - it feels lame...
It actually is also wrong as you can have multiple overlapping iserts.
That is one thing that I always fuind funny - people not reading the documentation.
SELECT SCOPE_IDENTITY()
returns the last identity value generated in a specific scope and is syntactically correct. It also is properly documented.
Isn't there a way to return the last inserted ID without using another query?
Yes. Ask for the number in the saame SQL batch.
INSERT (blablab9a); SELECT SCOPE_IDENTITY ();
as ONE string. ExecuteScalar.
You can have more than one SQL statement in one batch.
If you want to execute query from C# code & want to get last inserted id then you have to find the following code.
SqlConnection connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
connection.Open();
string sql = "Insert into [Order] (customer_id) values (" + Session["Customer_id"] + "); SELECT SCOPE_IDENTITY()";
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
var order_id = cmd.ExecuteScalar();
connection.Close();
Console.Write(order_id);

How to get string value from an OracleParameter object when using ExecuteNonQuery

As the code Shows below, I want to insert a row into a database table (oracle 11) and return a String-Value of the inserted row.
using (OracleCommand cmd = con.CreateCommand()) {
cmd.CommandText = "insert into foo values('foo','bar') returning idString into :lastIdParam";
cmd.Parameters.Add(new OracleParameter("lastIdParam", OracleDbType.Varchar2), ParameterDirection.ReturnValue);
cmd.ExecuteNonQuery(); // returning 1 (insert row successfully)
var result = cmd.Parameters["lastIdParam"].Value.ToString(); // == String.Empty
}
Debugging shows that lastIdParam.Value's value = Empty.String:
My Problem is, that I'm not getting the return string into my return-parameter but it will work when returning an integer value (like sequence no of inserted id). Cast Problem? ...?
The idString is filled if running the Statement directly (or if I just do something like returning 'ABC' into :myOutputParameter
Any ideas how to retrieve a string after inserting row?
Have you tried setting a size for the parameter? The default size is 0.
new OracleParameter("lastIdParam", OracleDbType.Varchar2, 128)
The idString is an expression which has no value in your context, unless it is a column name in your table. Therefore, it is epected to be empty. You may change your query like the example below and see what happens.
cmd.CommandText = "insert into foo values('foo','bar') returning hereYouHaveToUseAColumnFromTheFooTable into :lastIdParam";

ExecuteScalar returns value is not suitable

I use Enterprise Library and I have one problem:
string sql = "
UPDATE StackOverflow SET UserName = #UserName
WHERE Id = #Id
";
DbCommand cmd = base.Database.GetSqlStringCommand(sql);
base.Database.AddInParameter(cmd, "Id", DbType.Int32, StackOverflow.Id);
base.Database.AddInParameter(cmd, "UserName", DbType.Int32, StackOverflow.UserName);
int val = Convert.ToInt32(base.Database.ExecuteScalar(cmd));
Convert.ToInt32(base.Database.ExecuteScalar(cmd)) //returns 0.
I've read this article http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
The article says:
The function returns the new Identity column value if a new row was inserted, 0 on failure.
but I did not insert into that table - I only want to update and return updated row Id.
You should use ExecuteNonQuery in your case.
ExecuteScalar
Executes the query, and returns the first column of the first row in the result set returned by the query
ExecuteNonQuery
Executes a Transact-SQL statement against the connection and returns the number of rows affected
Your query doesn't return anything, so ExecuteScalar is not the right method to work with.
ExecuteNonQuery on the other side will give the correct information if your query has updated anything.
If you modify your SQL statement to the following, I think this will give you the result your expecting:
string sql = "
UPDATE StackOverflow SET UserName = #UserName
WHERE Id = #Id
RETURN #Id
";

Categories

Resources