ExecuteNonQuery() always returning -1

3.7k views Asked by At

I'm creating a login application with C# and SQL Server.

What my program does: it looks if the given username and password can be found in the database.

If it can be found, ExecuteNonQuery() should return 1 (1 row found).

If the combination doesn't exist, ExecuteNonQuery() should return something else.

But in my case, whenever I use a good or wrong combination, it always returns -1... how do I fix this?

I know, there are some existing posts for the same question, but it's still not fixed...

Also, what is the difference between ExecuteNonQuery() & ExecuteScalar()?

This is the query being sent:

private void btn_loginvolgende_Click(object sender, EventArgs e)
{
    gebruiker.Gebruikersnaam = Convert.ToString(tb_gebruikersnaamlogin.Text);
    gebruiker.Wachtwoord = Convert.ToString(tb_wachtwoordlogin.Text);
    gebruiker.Achternaam = "a";
    gebruiker.Geslacht = "a";
    gebruiker.Geslacht = "a";
    gebruiker.Huidiggewicht = 1;
    gebruiker.Streefgewicht = 1;
    gebruiker.Leeftijd = 1;
    gebruiker.Naam = "a";

    db.QueryToDatabase("Select count (*) from Gebruiker where Wachtwoord = @Wachtwoord AND Gebruikersnaam = @Gebruikersnaam;", gebruiker);
    Thread.Sleep(500);

    if (db.Success == false)
    {
        MessageBox.Show("Login gegevens kloppen niet!");
    }
    else if (db.Success == true)
    {
        MessageBox.Show("U bent met succes ingelogd");
    }
}

and this is my class:

public void QueryToDatabase(string commandText, Gebruikerklasse gebruiker)
{
    // nieuwe connectie maken
    // ontvangt de query vanuit 'buttonclick' en voert hem hier uit
    // als ExecuteNonQuery niet kan worden uitgevoerd is er iets fout gegaan. D.m.v een bool moet hij dan een bericht tonen
    using (SqlConnection conn = new SqlConnection(connectionString))
    using (SqlCommand cmd = new SqlCommand(commandText, conn))
    {
        conn.Open();

        cmd.Parameters.AddWithValue("@Naam", gebruiker.Naam);
        cmd.Parameters.AddWithValue("@Achternaam", gebruiker.Achternaam);
        cmd.Parameters.AddWithValue("@Leeftijd", gebruiker.Leeftijd);
        cmd.Parameters.AddWithValue("@Geslacht", gebruiker.Geslacht);
        cmd.Parameters.AddWithValue("@Huidiggewicht", gebruiker.Huidiggewicht);
        cmd.Parameters.AddWithValue("@Streefgewicht", gebruiker.Streefgewicht);
        cmd.Parameters.AddWithValue("@Gebruikersnaam", gebruiker.Gebruikersnaam);
        cmd.Parameters.AddWithValue("@Wachtwoord", gebruiker.Wachtwoord);

        int a = cmd.ExecuteNonQuery();

        if (a == 1)
        {
            Success = true;
        }
        else if (a == -1)
        {
            Success = false;
        }

        conn.Close();
    }
}
2

There are 2 answers

2
Steve On BEST ANSWER

It seems that you want a single method to do every possible task against a database. This is practically impossible. A better approach is to have specific methods in your class that do the interaction with a database

For example you could change your Gebruikerklasse and add a method called Exists where you can fine tune the interaction for the specific task. No need to create a lot of parameters when you need only two. Use the more performant ExecuteScalar (and correct) call to get your information back from the storage, etc....

public class Gebruikerklasse 
{
    ....
    public bool Exists()
    {
        string commandText = @"Select count (*) from Gebruiker 
                              where Wachtwoord = @Wachtwoord AND 
                             Gebruikersnaam = @Gebruikersnaam;", 
        using (SqlConnection conn = new SqlConnection(DBClass.GetConnectionString()))
        using (SqlCommand cmd = new SqlCommand(commandText, conn))
        {
            conn.Open();
            cmd.Parameters.AddWithValue("@Gebruikersnaam", gebruiker.Gebruikersnaam);
            cmd.Parameters.AddWithValue("@Wachtwoord", gebruiker.Wachtwoord);
            int a = Convert.ToInt32(cmd.ExecuteScalar());
            return (a > 0);
        }
    }
}

This should be only a first step in creating an OOP approach to your tasks. Next is to learn how to separate your model from your database code.

Side note: forcing a count of the table just to discover if an entry exists or not is a waste. There is a specific SQL statement that helps a lot here.
Search for IF EXISTS and read this article
Exists vs Count The battle never ends

0
Jeroen Stevens On

I know this questions has been answered. But I would like to add some additional information for you:

ExecuteNonQuery - runs a query and returns the affected rows.

ExecuteScalar - runs a query and returns the value of the first column of the first row.

ExecuteReader - runs a query and returns a SqlDataReader; that can be used to read the requested database records

I recently wrote a tutorial on this as well, including "memory management". Please see: http://jeroenstevens.blogspot.ca/2017/02/how-to-connect-netc-to-sql-database.html