【问题标题】:Stored Procedure to return Names with a given first letter via Search function通过搜索功能返回具有给定首字母的名称的存储过程
【发布时间】:2011-11-18 12:24:23
【问题描述】:

首先尝试这样的查询

SELECT *
FROM CUSTOMER
WHERE LEFT(NAME, 1) = 'A'

效果很好,但现在我希望它作为一个存储过程,并将“A”替换为这样的搜索词

CREATE PROCEDURE [dbo].[procCustomer_SelectByFirstLetter]
    @SearchTerm VARCHAR(50)
AS
SELECT  [Name]

FROM    [dbo].[Customer]
WHERE   LEFT(NAME, 1) = '@SearchTerm'
GO

此存储过程由 C# 方法调用,该方法使用包含所有字母 A-Z 的下拉列表

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {


            DataTable customerTable =  Customer.SelectByFirstLetter(Request.QueryString[DropDownList1.SelectedValue.ToString()]);
            CustomerRepeater.DataSource = customerTable;
            CustomerRepeater.DataBind();
            CustomerCountLabel.Text = customerTable.Rows.Count.ToString();            
    }

当我从下拉列表中选择一个字母时,Reapter 什么也没有显示。有任何想法吗?谢谢!

【问题讨论】:

  • 去掉变量名两边的单引号
  • 您需要考虑搜索词的长度。 IE,你不能在SP里做LEFT(xxx,1)。
  • 见下面我的帖子。也是大卫的最后一次编辑。

标签: c# sql search


【解决方案1】:

您仍在使用带引号的值,因此它会查找第一个字母等于字符串 "@SearchTerm" 的名称,这当然不会。

您需要删除引号:

WHERE LEFT(NAME, 1) = @SearchTerm

此外,您可能知道也可能不知道您可以通过LIKE 实现此目的:

WHERE NAME LIKE 'A%'

...或者

WHERE NAME LIKE @SearchTerm + '%'

...% 是任何东西的通配符。这样,传递 A 将搜索以字母 A 开头的任何内容,但传递 ABC 将搜索任何带有字母“ABC”的内容,而无需指定长度,就像在您的 LEFT 函数中一样。

更新
此外,您似乎错误地将参数传递给过程:

DataTable customerTable = Customer.SelectByFirstLetter(Request.QueryString[DropDownList1.SelectedValue.ToString()]);

在这里,您正在 QueryString 集合中寻找与您选择的值相匹配的键。因此,如果DropDownList1.SelectedValue.ToString() 产生“A”,它将寻找?A=...。您可能想改用以下内容:

DataTable customerTable = Customer.SelectByFirstLetter(DropDownList1.SelectedValue.ToString());

【讨论】:

  • 查看我对上一个用户的评论
  • 感谢您提供的信息...但仍然无法正常工作。我开始认为下拉列表中的信息没有被传递......?你觉得这个方法合适吗?
  • 您确定您已经执行了ALTER PROCEDURE 语句,以便保存更改吗?因为该代码可以工作(我刚刚测试过)。
  • 嗯,你确定 Request.QueryString[DropDownList1.SelectedValue.ToString()] 不应该只是 DropDownList1.SelectedValue.ToString() 吗? (请参阅我的更新)
  • 好的,现在我在选择字母时出现错误。用户代码未处理 HTTPException。错误发生在 CustomerRepeater.DataBind() 并且它说 System.Data.DataRowView 不包含名为“CustomerID”的属性。什么?!为什么返回 CustomerID
【解决方案2】:

试试这个...

LEFT(NAME, 1) = @SearchTerm 

而不是

LEFT(NAME, 1) = '@SearchTerm' 

【讨论】:

    【解决方案3】:

    如果您只想匹配第一个字符,您的 SP 应如下所示

    CREATE PROCEDURE [dbo].[procCustomer_SelectByFirstLetter]
        @SearchTerm CHAR(1)  
    AS  
        SELECT 
                  [Name]
            FROM    
                  [dbo].[Customer]  
            WHERE   
                  LEFT(NAME, 1) = @SearchTerm
    GO
    

    更一般地你可以这样做

    CREATE PROCEDURE [dbo].[procCustomer_SelectByNameStart]
        @SearchTerm VARCHAR(MAX) /*Use your column width here*/
    AS  
        SELECT 
                  [Name]
            FROM    
                  [dbo].[Customer] C
            WHERE   
                  C.[Name] LIKE @SearchTerm + '%'
    GO
    

    您可能还希望在结果集中包含 Customer 表的主键,但我认为为简洁起见省略了。

    【讨论】:

      【解决方案4】:

      您是否在 Page_Load-Event 中填写 DropDownList?

      如果是,请验证这是否发生在

      if (!Page.IsPostback)
      {
      }
      

      阻止。

      Page_Load 在 SelectedIndex_Changed 事件之前执行,因此如果您没有正确绑定 Dropdown,请将 Dropdown 的值重置为初始值,而不是您的搜索词。

      【讨论】:

        【解决方案5】:

        正如我在对您的问题的评论中提到的,不考虑搜索词的长度可能是您遇到的问题,但也有人建议使用 like 而不是 left 的另一种好方法。

        CREATE PROCEDURE [dbo].[procCustomer_SelectByFirstLetter]
            @SearchTerm VARCHAR(50)
        AS
        SELECT  [Name]
        
        FROM    [dbo].[Customer]
        WHERE   LEFT(NAME, LEN(@SearchTerm)) = @SearchTerm
        

        也就是说,经过进一步审查,这条线很可能是您的问题:

        Customer.SelectByFirstLetter(Request.QueryString[DropDownList1.SelectedValue.ToString()]);
        

        Request.QueryString[value] 将给你任何 Request.QueryString[value] 等于。我想你真的想要这个?

        Customer.SelectByFirstLetter(DropDownList1.SelectedValue.ToString());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-21
          • 1970-01-01
          相关资源
          最近更新 更多