【问题标题】:How to use LIKE % for two or more fields with OR in C#如何在 C# 中使用 OR 对两个或多个字段使用 LIKE %
【发布时间】:2017-02-07 11:51:33
【问题描述】:

我找不到我的问题的答案,所以我不得不提出新问题。即我想问你如何使用 LIKE +value from textbox+ 和 % - 通配符(缺少字母),但用于两个或多个字段。当我将以下代码用于一个字段时,它正在工作(我可以在我的数据库中搜索所有从“A”开始的名字):

"SELECT * FROM customer WHERE FirstName LIKE '"+TextBox1.Text + '%'+ "'";

但是当我尝试将它用于两个字段时,它不起作用,(a我无法在我的数据库中搜索,例如任何以“R”开头的名字或姓氏。我没有得到任何错误。什么也没发生):

"SELECT * FROM customer WHERE FirstName LIKE '"+TextBox1.Text + '%'+ "' OR LastName LIKE '" +TextBox2.Text + '%'+"'";

提前感谢您的任何建议。

【问题讨论】:

  • 请不要将用户输入直接插入到您的查询中,而是使用参数化查询。您的代码对SQL Injection开放!
  • 生成的 SQL 是什么?
  • 定义它不起作用
  • 什么是“什么都没有发生”?它冻结了吗?或者你得到一个空的结果集?您是否尝试在 SQL Management Studio 或任何其他数据库界面中运行查询以检查它是否有效?也许你的输入数据已经不正确(或者你已经用 sql 注入欺骗了自己)。
  • @RenéVogt,你说的很对,我会改的,不过只是为了我的测试。

标签: c# sql sql-like


【解决方案1】:

您不应该通过字符串连接来创建查询,否则您会将您的应用程序暴露给SQL Injection。更好地使用带参数的命令 - 这也将帮助您无需过多考虑可能导致您当前问题的字符串转义。

using (SqlCommand cmd = new SqlCommand())
using (SqlConnection conn = new SqlConnection("connectionString"))
{
       cmd.CommandText = "SELECT * FROM customer WHERE FirstName LIKE @first OR LastName LIKE @second";
       cmd.Parameters.Add(new SqlParameter("first", SqlDbType.NVarChar, 255).Value = "%" + TextBox1.Text + "%");
       cmd.Parameters.Add(new SqlParameter("second", SqlDbType.NVarChar, 255).Value = "%" + TextBox2.Text + "%");
       // todo: execute
}

您还可以验证您当前在应用程序中创建的查询(只需在执行前设置断点或简单地将其记录到文件 f.e.)是否正在返回您期望的结果,以防您直接在服务器上执行它。这可以帮助您检查更多问题。

【讨论】:

  • 我已经按照您的建议更正了我的代码,它按预期工作。
【解决方案2】:

我看到@Jaroslav Kadlec 是如何做到的,他没有错,但他有一个问题。他正在使用被贬低的方法。添加参数有一个新方法:

using (SqlConnection conn = new SqlConnection("connectionString")){
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
    cmd.CommandText = "SELECT * FROM customer WHERE FirstName LIKE @first OR LastName LIKE @second";
    cmd.Parameters.AddWithValue("@first", TextBox1.Text + "%");
    cmd.Parameters.AddWithValue("@second", TextBox2.Text + "%");
}}

【讨论】:

  • AddWithValue 有其自身的局限性。使用显式类型和大小创建 SqlParameters 会产生可预测的结果
  • @RowlandShaw +1。另外 AddWithValue 不允许您为 nvarchar 类型指定大小约束 - 请查看我的答案中的用法。如果你这样做,你就是在为 SQL Server 做善意的服务。
【解决方案3】:

如果您有动态数量的令牌,完成任务的一种复杂方法是​​定义一个临时表并与之连接:

using (var conn = new SqlConnection(connectionStr))
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        var querySb = new StringBuilder(@"
            CREATE TABLE #temp (Token NVARCHAR(20) NOT NULL)");

        //tokensArray will contain texts from your text boxes
        for (int i = 0; i < tokensArray.Length; i ++)
        {
            querySb.Append($"INSERT INTO #temp VALUES(@p{i})");

            // parameterized query, to protect against SQL injection (input is coming from user)
            cmd.Parameters.AddWithValue($"@p{i}", $"%{token}%");
        }

        cmd.CommandType = CommandType.Text;
        cmd.CommandText = querySb.ToString();

        querySb.Append(@"; 
SELECT C.* 
FROM customer C 
    JOIN #temp T ON C.FirstName LIKE T.Token";

        // execute stuff
    }
}

您还可以考虑在连接字符串中发送令牌,并使用存储过程将它们拆分并在 T-SQL 中进行过滤。

归功于this answer

【讨论】:

  • 以这种方式使用会更好cmd.Parameters.Add(new SqlParameter($"@p{i}", SqlDbType.NVarChar, 255).Value = $"%{token}%"); 这可以让您提示 SQL Server 将使用哪种数据类型的大小 == 小的性能优势。
  • 有趣的想法。我从来没有想过。谢谢。
【解决方案4】:

最好先将文本框值分配给字符串变量,然后按如下方式使用它们

String Firsttext = TextBox1.Text;
String SecondText = TextBox2.Text;

那么你可以如下使用它

"SELECT * FROM customer WHERE FirstName LIKE '"+ Firsttext + "%" + "' OR LastName LIKE '" +SecondText + "%"+"'";

【讨论】:

  • 当心 Ved 这会让你很容易受到 sql 注入的攻击!
  • 无意冒犯我会怀疑这是一种好的做法。最好将表单逻辑与连接脚本的部分完全分开。然后建议使用 LIKE ...'"+Firsttext + '%'... 是根本错误的。这似乎不是原始问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 2017-11-22
  • 2018-07-15
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
相关资源
最近更新 更多