【问题标题】:SqlDataSource SelectCommand using LIKE does not work使用 LIKE 的 SqlDataSource SelectCommand 不起作用
【发布时间】:2010-10-15 19:39:21
【问题描述】:

我在SelectCommand 中有以下 T-SQL:

SELECT h.Business,
hrl.frn
FROM registration hrl
INNER JOIN holder h on h.call = hrl.call
WHERE 
(h.Business like '%' + @business + '%' and h.Business is not null) 
and 
(hrl.frn = @frn and hrl.frn is not null)

businessfrn 与控制参数相关联,即使其中一个或两个都留空,它也应该返回数据,但如果我只为 frn 输入数据,它不会返回任何内容。我认为我的 T-SQL 没有做正确的事情,我也不确定我是否正确处理了 like

如果两个文本框都为空,它应该返回所有数据。如果输入了frn,但business 留空,它应该只返回与frn 相关的数据。如果输入了business,但frn 留空,它应该返回所有匹配likebusiness。如果两者都输入,它应该只返回匹配frnbusiness 的数据。

另外,我不确定是否真的需要 and is not null

protected void btnSearch_Click(object sender, EventArgs e)
{
    if (txtFRN.Text == "")
        frn = null;

    if (txtBusiness.Text == "")
        business = null;

    sqlDsMaster.SelectParameters[frn].DefaultValue = frn;
    sqlDsMaster.SelectParameters[business].DefaultValue = business;

    sqlDsMaster.DataBind();
}

当它碰到这一行时,上面会抛出一个“对象引用未设置为实例”:

sqlDsMaster.SelectParameters[frn].DefaultValue = frn;

frnbusiness 是属性。


这里是SearchMaster 存储过程:

CREAETE PROCEDURE SearchMaster
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS
SELECT h.Business,
       hrl.frn
FROM registration hrl
INNER JOIN holder h on h.call = hrl.call
WHERE (@business IS NULL OR h.Business like '%' + @business + '%') 
  AND (@frn IS NULL OR hrl.frn = @frn)

这里是SearchDetails 存储过程:

CREATE PROCEDURE SearchDetails
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS
SELECT hrl.call 
FROM registration hrl 
INNER JOIN holder h ON h.call = hrl.call
WHERE (@business IS NULL OR h.Business LIKE '%' + @business + '%') 
      AND (@frn IS NULL OR hrl.frn = @frn)

这是SearchMaster 过程的SqlDataSource

<asp:SqlDataSource ID="sqlDsDetails" 
                   runat="server" 
                   ConnectionString="<%$ ConnectionStrings:cnxString %>
                   SelectCommandType="StoredProcedure" 
                   SelectCommand="SearchMaster">
  <SelectParameters>
    <asp:ControlParameter Name="business" ControlID="txtBusiness" 
                          Type="String" PropertyName="Text"  
                          ConvertEmptyStringToNull="true" />
    <asp:ControlParameter Name="frn" ControlID="txtFRN" 
                          Type="String" PropertyName="Text"
                          ConvertEmptyStringToNull="true"/>
  </SelectParameters>
</asp:SqlDataSource>

这是SearchDetails 过程的SqlDataSource

<asp:SqlDataSource ID="sqlDsDetails" 
                   runat="server" 
                   ConnectionString="<%$ ConnectionStrings:cnxString %>
                   SelectCommandType="StoredProcedure" 
                   SelectCommand="SearchDetails">
  <SelectParameters>
    <asp:Parameter Name="frn" Type="String" DefaultValue="" 
                   ConvertEmptyStringToNull="true" />
    <asp:Parameter Name="business" Type="String" DefaultValue="" 
                   ConvertEmptyStringToNull="true" />
  </SelectParameters>
</asp:SqlDataSource>

这里是绑定SqlDsMaster的按钮点击:

protected void btnSearch_Click(object sender, EventArgs e)
{
    sqlDsMaster.DataBind();
}

这是为详细信息创建行的gvMaster_RowCreated

protected void gvMaster_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        SqlDataSource ctrl = 
        e.Row.FindControl("sqlDsDetails") as SqlDataSource;

        if (ctrl != null && e.Row.DataItem != null)
        {
            ctrl.SelectParameters["frn"].DefaultValue = 
            ((DataRowView)e.Row.DataItem)["frn"].ToString();

            ctrl.SelectParameters["business"].DefaultValue = 
            ((DataRowView)e.Row.DataItem)["business"].ToString();
         }
     }
 }

SearchMasterSearchDetails 如果我通过 SQL Server Management Studio 运行它,它们都可以工作,如果我输入businessfrn 的两个数据,它可以工作,但如果我只输入一个,则不会返回任何数据。参数设置是否正确?另外,如果我在程序中将参数初始化为null,是否还需要使用ConvertEmptyStringToNull

【问题讨论】:

  • 当以 '%' 开头的字符串时要小心,因为这意味着您将无法在过滤列上使用索引。
  • 详细说明您的意思。在这种情况下,我别无选择,我必须使用 LIKE

标签: c# asp.net tsql sqldatasource


【解决方案1】:

"and is not null"

存储过程是正确的:(@frn IS NULL OR hrl.frn = @frn)。如果frnnull 或匹配,您想选择任何行。同样的模式也适用于business 属性。

NullReferenceException

sqlDsMaster.SelectParameters[frn].DefaultValue = frn;

这会失败,因为您使用frn 属性的值(可能是null)而不是字符串"frn" 作为SelectParameters 的索引。您在下一行使用 business 而不是 "business" 遇到相同的错误。

ConvertEmptyStringToNull

我会反过来提出问题:如果您使用ConvertEmptyStringToNull,为什么要让调用者负担相同的功能?除非空字符串是 frnbusiness 的有效值,否则我会保留 ConvertEmptyStringToNull 设置并且不在调用者中关心它。

我希望这能回答你所有的问题。

【讨论】:

    【解决方案2】:

    我会这样做:

    where (@business is null
              or @business = ''
              or h.Business like '%' + @business + '%')
          and (@frn is null
                  or @frn = ''
                  or hrl.frn = @frn)
    

    如果您在传递空搜索字符串之前将其设为 null,则可以跳过 @yyy = '' 部分。

    【讨论】:

    • 您能详细说明一下吗?谢谢!
    • 这种格式是不久前在一个问题中向我建议的,它完美无缺。我建议先测试空字符串,因为它使最终查询更具可读性。
    • 哦,我提到的问题在这里找到:stackoverflow.com/questions/205526/…
    • 好的,我会检查的。例如,我有一个名为 txtFRN 的文本框,而我只是设置了一个 。如果 txtFRN 为空,有没有办法可以将 @frn 设置为 null。
    • 我只是设置 SelectParameters[frn] = null
    【解决方案3】:

    改变

    "并且 h.Business 不为空"

    “或 h.Business 为空”

    "并且 hrl.frn 不为空"

    “或 hrl.frn 为空”

    当这些参数为空时,这将返回所有内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-20
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      相关资源
      最近更新 更多