OleDb where like statement error

1.7k views Asked by At

I am trying to make a search in a oledb database using an ID (integer) or a name (string) through a windows form application. The user selects the type of search with a combobox, as the possible search type are different I use a switch to create two different query:

        string Combo = this.comboBox1.SelectedItem.ToString();
        string text = this.textBox1.Text;
        connection.Open();
        OleDbCommand command = null;
        switch (Combo)
        {
            case "Nombre":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ? OR ? LIKE ?", connection);
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");
                break;
            case "Id":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ?", connection);
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", Convert.ToInt32(text));
                //command.Parameters.AddWithValue("?", "%" + Convert.ToInt32(text) + "%");
                break;
        }
        try
        {
            OleDbDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                string list = "";
                list += reader.GetValue(0).ToString() + "\t";
                list += reader.GetValue(1).ToString();
                this.listBox1.Items.Add(list);
            }
        }
        catch (Exception ex)
        {
            DialogResult result = MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
            this.Close();
        }
        connection.Close();

The combobox starts by default with Nombre (Name in Spanish)it shows all of the items in the db (as I wanted).

The first problem starts when the user inserts a text in the textbox. For example, when I insert a "p" in the textbox it has to show everything that contains "p" (uppercase and lowercase) inside the database which it does not.

The second problem is when the user selects in the combobox Id, this results in an error Input String has not a correct format (using commented and non-commented instruction).

Any idea how to change the code to read the items I wanna search in the database?


EDIT

Thanks for the apportation. Seeing the answers I will try to answer them (too much information to put it as a comment). First I changed the code as Jon says, now it is working correctly when Nombre is selected:

        this.listBox1.Items.Clear();
        string Combo = this.comboBox1.SelectedItem.ToString();
        string text = this.textBox1.Text;
        connection.Open();
        OleDbCommand command = null;
        switch (Combo)
        {
            case "Nombre":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE Nombre LIKE ? OR Nombre LIKE ?", connection);
                command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
                command.Parameters.AddWithValue("?", "%" + UppercaseFirst(text) + "%");
                break;
            case "Id":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ID LIKE ?", connection);
                command.Parameters.AddWithValue("?", "%" + Convert.ToInt32(text) + "%");
                break;
        }
        try
        {
            OleDbDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                string list = "";
                list += reader.GetValue(0).ToString() + "\t";
                list += reader.GetValue(1).ToString();
                this.listBox1.Items.Add(list);
            }
        }
        catch (Exception ex)
        {
            DialogResult result = MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
            this.Close();
        }
        connection.Close();

The part for Id is still not working this way.

Second: *"If ID is a numeric field then select ... WHERE ID should not use LIKE". I think this is necessary. I do not need to search a number, I need to search a number like the inserted. For example, if the user selects Id and inserts a 1, the result has not to be only 1, it can be 11, 111, 231, etc.. any number containing a 1 (as happens with Nombre).

Finally: Uppercase and Lowercase functions are necessary. I tested the code with and without them the result is more complete with these functions. Here is the code:

static string LowercaseFirst(string s)
        {
            // Check for empty string.
            if (string.IsNullOrEmpty(s))
            {
                return string.Empty;
            }
            // Return char and concat substring.
            return char.ToLower(s[0]) + s.Substring(1);
}
static string UppercaseFirst(string s)
{
            // Check for empty string.
            if (string.IsNullOrEmpty(s))
            {
                return string.Empty;
            }
            // Return char and concat substring.
            return char.ToUpper(s[0]) + s.Substring(1);
}
1

There are 1 answers

2
Jon Skeet On

The problem (or at least one problem) is that you're trying to use a parameter for a column name. You can't do that - only values can be parameterized. Column and table names have to be part of the SQL itself.

So for example, this:

case "Nombre":
    command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ? OR ? LIKE ?", connection);
    command.Parameters.AddWithValue("?", Combo);
    command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
    command.Parameters.AddWithValue("?", Combo);
    command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");

should be:

case "Nombre":
    command = new OleDbCommand(
        "SELECT Id, Nombre  FROM ARTICULOS WHERE Nombre LIKE ? OR Nombre LIKE ?", 
        connection);
    command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
    command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");