【问题标题】:multiple field search using stored procedure使用存储过程的多字段搜索
【发布时间】:2018-08-24 10:27:19
【问题描述】:

我的表中有 24 个字段,它们都是 nvarchar 类型,除了一个 int 类型,它是 ID 现在我想在所有字段中搜索用户在 textBox 中写入的任何文本,例如,如果用户会写“ 20”在文本框中,它应该显示所有记录,他们的字段有“20”。在数据网格视图中返回任何东西!!
这是我的存储过程:

create proc searchClientProfile
@search nvarchar(255)
as
select * from clientProfile where convert(nvarchar,ID)+compName+Addres+compPhone+compEmail+compWebsite+shipAddress+shipPhone+primeContact+primePhone+primeEmail+secContact+secPhone+secEmail+sector+established+industry+anulPrch+country+region+town+stat+city+zip like '%@search%'

这是我的 textBox TextChanged 事件中的代码:

cmd = new SqlCommand("searchClientProfile", cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter[] parm = new SqlParameter[1];
parm[0] = new SqlParameter("@search", SqlDbType.NVarChar, 255);
parm[0].Value = searchClientTxt.Text.Trim();
cmd.Parameters.AddRange(parm);
da = new SqlDataAdapter(cmd);
da.Fill(getSearchedClientProfiles);
searchClientsDgv.DataSource = getSearchedClientProfiles;

【问题讨论】:

  • 如果其中一列为空,则整个拼接结果为空。比较 select 'test'+nullselect 'test'+ISNULL(null,'')
  • 您需要阅读这篇文章并重新考虑您的搜索逻辑。并且绝对不要选择*,只选择你需要的列。 sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries 请注意,使用前导通配符搜索会使索引变得无用。因此,在所有这些列中执行此操作对性能来说会很糟糕。

标签: c# sql-server winforms search stored-procedures


【解决方案1】:

如果我理解正确,您想检查 20 列中是否包含您的搜索查询。它应该看起来像这样:

select * 
from clientProfile 
where convert(nvarchar,ID) like '%@search%'
OR compName like '% ' + @search + '%'
OR Addres like '%'+@search + '%'
OR compPhone like '%'+@search + '%'
OR compEmail like '%'+@search + '%'
OR compWebsite like '%'+@search + '%'
OR shipAddress like '%'+@search + '%'
OR shipPhone like '%'+@search + '%'
OR primeContact like '%'+@search + '%'
OR primePhone like '%'+@search + '%'
OR primeEmail like '%'+@search + '%'
OR secContact like '%'+@search + '%'
OR secPhone like '%'+@search + '%'
OR secEmail like '%'+@search + '%'
OR sector like '%'+@search + '%'
OR established like '%'+@search + '%'
OR industry like '%'+@search + '%'
OR anulPrch like '%'+@search + '%'
OR country like '%'+@search + '%'
OR region like '%'+@search + '%'
OR town like '%'+@search + '%'
OR stat like '%'+@search + '%'
OR city like '%'+@search + '%'
OR zip like '%'+@search + '%'

我不知道你是如何构建你的应用程序的,但是这种查询的性能不会令人惊叹

【讨论】:

    【解决方案2】:

    在串联中,您应该处理 NULL 值。可以使用ISNULLCONCAT 来完成。

    另外,如果在ecContactsecPhone 中有相应的search 怎么办?您将它们连接为search 并进行匹配。您需要使用分隔符。

    如果我是你,我只会为列编写条件检查。

    create proc searchClientProfile
    ' + @search + ' nvarchar(255)
    as
    select * from clientProfile where convert(nvarchar,ID) like '%' + @search + '%' OR compName like '%' + @search + '%' OR Addres like '%' + @search + '%' OR compPhone like '%' + @search + '%' OR compEmail like '%' + @search + '%' OR compWebsite like '%' + @search + '%' OR shipAddress like '%' + @search + '%' OR shipPhone like '%' + @search + '%' OR primeContact like '%' + @search + '%' OR primePhone like '%' + @search + '%' OR primeEmail like '%' + @search + '%' OR secContact like '%' + @search + '%' OR secPhone like '%' + @search + '%' OR secEmail like '%' + @search + '%' OR sector like '%' + @search + '%' OR established like '%' + @search + '%' OR industry like '%' + @search + '%' OR anulPrch like '%' + @search + '%' OR country like '%' + @search + '%' OR region like '%' + @search + '%' OR town like '%' + @search + '%' OR stat like '%' + @search + '%' OR city like '%' + @search + '%' OR zip like '%' + @search + '%'
    

    【讨论】:

      【解决方案3】:

      另一种选择(显然不是 sargable)。

      注意:别名是必需的。

      示例

      Select * 
       From clientProfil A
       Where (Select A.* for XML Raw) like '%'+@search+'%'
      

      【讨论】:

      • 这很有趣。以前没有见过这种方法。
      • @SeanLange 只是一些性能不是最重要的懒惰编码。
      • 是的,我可以看到性能会有点问题的地方,但对于一些低俗和肮脏的研究来说也是一个很酷的技巧。我可以看到对“搜索每个表的每个字段以查找 x”的简单修改。
      • @JohnCappelletti 不错且快速的方法。如果性能很重要呢?在这种情况下,如何在结果集中返回的每一列中搜索字符串。
      【解决方案4】:

      非常感谢大家的帮助...形成看到的答案,我将我的存储过程特别是从 '%@search%' 更改为 '%'+@search+'%' 在我的 C# 代码中的第二个部分在 TextChanged 事件中添加了一行代码,用于清除数据网格视图的先前内容,因此现在 TextChanged 事件的代码如下所示:

      getSearchedClientProfiles.Clear();
      cmd = new SqlCommand("searchClientProfile", cn);
      cmd.CommandType = CommandType.StoredProcedure;
      SqlParameter[] parm = new SqlParameter[1];
      parm[0] = new SqlParameter("@search", SqlDbType.NVarChar, 255);
      parm[0].Value = searchClientTxt.Text.Trim();
      cmd.Parameters.AddRange(parm);
      da = new SqlDataAdapter(cmd);
      da.Fill(getSearchedClientProfiles);
      searchClientsDgv.DataSource = getSearchedClientProfiles;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多