【问题标题】:Ignore empty textboxes while searching in database在数据库中搜索时忽略空文本框
【发布时间】:2017-05-19 14:46:31
【问题描述】:

此代码能够根据搜索表单文本框中提供的值搜索并将数据加载到DataGridView。如果我将任何文本框留空,则没有搜索结果,因为 SQL 查询与“AND”组合。

如何在搜索时忽略空文本框(来自 SQL 查询或 C# 代码)?

private void btnSearch_Click(object sender, EventArgs e)
{
    DataSet ds = new DataSet();

    String select = "SELECT DocumentNo, Revision, DocumentTitle, DocumentType
                     FROM DocumentLog
                     WHERE DocumentNo Like '%" + tbxDocumentNo.Text + "%'
                       AND Revision Like '%" + tbxRevision.Text + "%'
                       AND DocumentTitle Like '%" + tbxDocumentTitle.Text + "%'
                       AND DocumentType '%" + tbxDocumentType.Text + "%'"
                       AND IsDeleted = '0';

    SqlConnection conn = DBConnection.openConnection();
    SqlCommand command = new SqlCommand(select, conn);

    SqlDataAdapter da = new SqlDataAdapter(command);
    da.Fill(ds, "DocumentLog");

    dgvTracking.AutoGenerateColumns = false;
    dgvTracking.DataSource = ds.Tables["DocumentLog"];
}

【问题讨论】:

  • 请使用绑定参数,您的代码容易受到 SQL 注入攻击。
  • 为什么AND IsDeleted = '0' 行在您的查询字符串之外?

标签: c# sql-server search


【解决方案1】:

您好,您可以为此使用一些查询逻辑,例如查询可以是:

Select DocumentNo , Revision, DocumentTitle, DocumentType 
FROM DocumentLog 
WHERE (DocumentNo Like '%"+tbxDocumentNo.Text+"%' OR tbxDocumentNo.Text = '') AND
(Revision Like '%"+tbxRevision.Text+"%' OR Revision = '') AND 
(DocumentTitle Like '%"+tbxDocumentTitle.Text+"%' OR DocumentTitle = '') AND
DocumentType '%"+tbxDocumentType.Text+"%'";AND IsDeleted='0'

【讨论】:

  • 我不明白这有什么帮助?当未给出字段的值时,OP 希望省略字段的子句。
【解决方案2】:

如果您不希望 SQL 命令包含子句 AND Revision Like '',则需要停止将 SQL 命令硬编码为单个字符串,而是根据输入框构建该字符串。

StringBuilder sqlCommandText = new StringBuilder();

sqlCommandText.Append("Select DocumentNo , Revision, DocumentTitle, DocumentType FROM DocumentLog WHERE IsDeleted = 0");

if(!string.IsNullOrEmpty(tbxRevision.Text))
{
    sqlCommandText.Append(" AND Revision Like @revision");
    command.Parameters.Add("@revision", tbxRevision.Text);
}

// do this for all fields

command.CommandText = sqlCommandText.ToString();   

【讨论】:

    【解决方案3】:
    • 首先你必须用参数化查询替换串联的字符串查询以避免注入,
    • 其次,您可以使用String.IsNullOrEmpty 来检查该值是否为空或空,然后再将它们添加到where 子句中。
    • 您需要注意的第三件事是多个条件分隔符AND,如果您在第二个条件(tbxRevision)的开头添加然后,如果tbxDocumentNo 为空或为空,则查询将出错。与最后一个条件类似,如果最后一个条件为假,则查询将以AND 结束,这也是一个错误,为了避免这些,我们可以将IsDeleted='0' 作为第一个条件,就像我在下面的代码中所做的那样,

    请看:

    string querySQL = "Select DocumentNo , Revision, DocumentTitle, DocumentType FROM DocumentLog WHERE IsDeleted='0'";
    using(SqlConnection conSQL = DBConnection.openConnection())
    {
        using(SqlCommand cmdSQL = new SqlCommand())
        {
            if(!string.IsNullOrEmpty(tbxDocumentNo.Text))
            {
                querySQL += "AND  DocumentNo Like @DocumentNo";
                cmdSQL.Parameters.Add("@DocumentNo", SqlDbType.VarChar).Value = "%" + tbxDocumentNo.Text + "%";
            }
    
            // Add rest of conditions here like this
    
            cmdSQL.CommandText=querySQL;
            cmdSQL.Connection = conSQL;
        SqlDataAdapter da = new SqlDataAdapter(cmdSQL);                                     
        }
    }
    

    【讨论】:

    • 您可以作弊并使用始终硬编码的 IsDeleted=0 而不是 1=1 :)
    • @nvoigt:谢谢,你是对的,我错过了那个条件;反正我已经更新了答案
    猜你喜欢
    • 2019-03-01
    • 2018-08-24
    • 2011-09-15
    • 2021-07-21
    • 1970-01-01
    • 2014-02-16
    • 2010-11-20
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多