【问题标题】:Retrieve all the rows in a table with a SELECT WHERE query with multiple parameterized conditions使用具有多个参数化条件的 SELECT WHERE 查询检索表中的所有行
【发布时间】:2018-12-05 10:48:39
【问题描述】:

我正在尝试从格式如下的 SQLite 数据库中检索一些数据:

表格

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)

【问题讨论】:

  • 是什么让你觉得你做错了什么?
  • 运行代码时是否报错?还是返回错误值?
  • @Caius Jard 我的错,用更具体的要求编辑了我的问题。
  • 它返回了哪些不应该返回的行? (这一系列问题正在发展你解决问题的思维过程,以及改进你向那些不知道你的系统如何运作的人提问的方式——本质上它是在教你钓鱼而不是给你一条鱼)
  • @Haldo 谢谢!尽管使用 SQLite 似乎语法是不同的 IFNULL(x, y) 而不是 ISNULL(x, y) 这似乎是一种魅力!再次将其作为 anwser 发布,我会相应地标记它。

标签: c# sql sqlite


【解决方案1】:

根据您的 cmets,看起来正在发生的事情是 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 的情况。

【讨论】:

    【解决方案2】:

    如果我没听错的话,您希望返回至少与传递的参数之一匹配的行。 因此,首先您应该添加一个检查,确保至少有一个参数不为空。在我看来,它应该在 Customer 构造函数中,(因为它必须让一个带有所有空参数的客户有什么意义?)。 Java constructor style: check parameters aren't 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)
    

    【讨论】:

      猜你喜欢
      • 2015-01-19
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多