Извлечь все строки в таблице с помощью запроса SELECT WHERE с несколькими параметризованными условиями - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь получить некоторые данные из базы данных SQLite, отформатированной следующим образом:

TABLE

Customers

КОЛОННЫ

id | firstName | lastName | address | phone | email | notes

У меня есть несколько TextBox и DataGridView для отображения данных от клиентов.Я пытаюсь найти и отобразить в DataGridView любую строку, которая соответствует содержимому любого TextBox.Код выглядит следующим образом, но я не могу понять, что я делаю неправильно с моим оператором SQL:

public static DataTable RecoverCustomer(Customer customer)
    {
        var connection = new SQLiteConnection("Data Source = prova.sqlite; Version=3;");

        var command = connection.CreateCommand();
        command.CommandText = "SELECT * FROM customers WHERE firstName = @firstName OR lastName = @lastName OR address = @address OR phone = @phone OR email = @email OR notes = @notes";
        command.Parameters.AddWithValue("@firstName", customer.FirstName);
        command.Parameters.AddWithValue("@lastName", customer.LastName);
        command.Parameters.AddWithValue("@address", customer.Address);
        command.Parameters.AddWithValue("@phone", customer.Phone);
        command.Parameters.AddWithValue("@email", customer.Email);
        command.Parameters.AddWithValue("@notes", customer.Notes);

        var dataAdapter = new SQLiteDataAdapter();
        var dataTable = new DataTable();

        connection.Open();
        dataAdapter.SelectCommand = command;
        dataAdapter.Fill(dataTable);
        connection.Close();

        return dataTable;
    }

Моя проблема в том, что этот код возвращает на несколько строк больше, чем должен.Может быть потому, что при добавлении нового клиента я не проверяю, есть ли какое-либо пустое поле, и, таким образом, возвращаю эти строки, когда я ищу клиента по этому коду? Если да, как я могу его уменьшить?Вот код, который я использую для добавления нового клиента в таблицу:

public static void CreateCustomer(Customer customer)
    {
        var connection = new SQLiteConnection("Data Source = prova.sqlite; Version=3;");
        var command = connection.CreateCommand();
        command.CommandText = "INSERT INTO customers (firstName, lastName, address, phone, email, notes) VALUES (@firstName, @lastName, @address, @phone, @email, @notes)";
        command.Parameters.AddWithValue("@firstName", customer.FirstName);
        command.Parameters.AddWithValue("@lastName", customer.LastName);
        command.Parameters.AddWithValue("@address", customer.Address);
        command.Parameters.AddWithValue("@phone", customer.Phone);
        command.Parameters.AddWithValue("@email", customer.Email);
        command.Parameters.AddWithValue("@notes", customer.Notes);

        connection.Open();
        command.ExecuteNonQuery();
        connection.Close();
    }

РЕДАКТИРОВАТЬ

Благодаря @Haldo я исправил свой оператор SQL, который соответствовал пустомупространства и это работает.Правильное утверждение:

SELECT * FROM customers WHERE (IFNULL(@firstName, '') <> '' AND firstName = @firstName) OR (IFNULL(@lastName, '') <> '' AND lastName = @lastName) OR (IFNULL(@address, '') <> '' AND address = @address) OR (IFNULL(@phone, '') <> '' AND phone = @phone) OR (IFNULL(@email, '') <> '' AND email = @email) OR (IFNULL(@notes, '') <> '' AND notes = @notes)

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Если я правильно понял, вы хотите вернуть строки, которые соответствуют хотя бы одному из переданных параметров.Поэтому сначала вы должны добавить проверку, что есть хотя бы один параметр, который не является нулевым.По моему мнению, это должно быть в конструкторе Customer, (что означает, что это значит иметь клиента со всеми нулевыми параметрами?). Стиль конструктора Java: проверьте, что параметры не равны нулю Затем вы можете изменить выражение select на что-то вроде этого:

SELECT * FROM customers
WHERE ( firstName = @firstName AND @firstName IS NOT NULL)
OR ( lastName = @lastName AND @lastName IS NOT NULL)
OR ( address = @address AND @address IS NOT NULL)
OR ( phone = @phone AND @phone IS NOT NULL)
OR ( email = @email AND @email IS NOT NULL)
OR ( notes = @notes AND @notes IS NOT NULL)
0 голосов
/ 05 декабря 2018

Исходя из ваших комментариев, похоже, что происходит то, что оператор SQL Select соответствует пустым / нулевым значениям, поэтому возвращается больше строк, чем ожидалось.

Вы хотите сопоставлять результаты только тогда, когда параметры имеютценность.Таким образом, изменение оператора SELECT ниже должно работать:

SELECT * FROM customers 
    WHERE (IFNULL(@firstName, '') <> '' AND firstName = @firstName) 
    OR (IFNULL(@lastName, '') <> '' AND lastName = @lastName)
    OR (IFNULL(@address, '') <> '' AND address = @address)
    OR (IFNULL(@phone, '') <> '' AND phone = @phone)
    OR (IFNULL(@email, '') <> '' AND email = @email)
    OR (IFNULL(@notes, '') <> '' AND notes = @notes)

При этом используется IFNULL (для sqlite), но тот же результат может быть достигнут с помощью ISNULL на сервере SQL.Использование IFNULL будет обрабатывать случай, когда параметром является пустая строка '' или NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...