簡體   English   中英

使用具有多個參數化條件的SELECT WHERE查詢檢索表中的所有行

[英]Retrieve all the rows in a table with a SELECT WHERE query with multiple parameterized conditions

我正在嘗試從格式如下的SQLite數據庫檢索一些數據:

Customers

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

我有幾個TextBoxes和一個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)

根據您的注釋,看起來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),但是在SQL Server中使用ISNULL可以實現相同的結果。 使用IFNULL將處理參數為空字符串''或NULL的情況。

如果我說對了,您想返回至少與傳遞的參數之一匹配的行。 因此,首先應添加一個檢查,以確保至少有一個不為null的參數。 在我看來,它應該在Customer構造函數中(因為它必須擁有一個具有所有空參數的客戶,這意味着什么?)。 Java構造函數樣式:check參數不為null然后可以將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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM