【问题标题】:Why does the following bring back data only when both parameters are set?为什么只有在设置了两个参数时,以下才会带回数据?
【发布时间】:2009-03-27 18:10:08
【问题描述】:

如果我在 Sql Management Studio 中运行 SearchMaster 和 SearchDetails 这两个过程,当我在设计视图中设置存储过程时测试查询时,SearchMaster 甚至运行良好,但是当我运行它时,没有行如果我只输入 frn 或业务的信息,则创建。如果我同时输入,如果匹配,我会得到数据。参数设置是否正确?另外,如果我在程序中将参数初始化为null,是否还需要使用ConvertEmptyStringToNull?

这是 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 StoredProcedure:

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();
         }
     }
 }

我运行了 SQL 探查器,当只输入一个参数时,探查器甚至没有显示过程正在运行。当我输入这两个参数时,程序显示在分析器中运行。

【问题讨论】:

  • 根据您的上一条评论,我 100% 确定这将解决它:确保在您的数据源上设置 CancelSelectOnNullParameter="False"

标签: c# asp.net sqldatasource


【解决方案1】:

我的猜测是,对于您认为为 null 的情况,它仍在传递一个空字符串。您可以通过以下方式排除这种情况:

CREATE PROCEDURE SearchDetails
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS

SELECT @business = NULLIF(@business, ''),
       @frn = NULLIF(@frn, '')

 SELECT hrl.call // etc

如果它开始工作,它传递的是空字符串。

【讨论】:

  • 谢谢 Marc,我现在就试试这个并告诉你。
  • 由于我不了解 t-sql,你能把我放在哪里测试一下吗?
  • 我也有 ConvertEmptyStringsToNull = "true" 我认为可以防止空字符串被传递,另外在过程中,我将参数初始化为 null。此外,如果我在 Sql Management Studio 中使用 1 个参数的空字符串运行该过程,它仍然会返回数据。
  • 哇,我用 tsql 10 年了,从来没有用过 NullIf,我经常用 IsNull,但 NullIf 一定是不知怎的被我溜走了。
【解决方案2】:

我怀疑 Marc Gravell 是对的。

尝试以下测试:

 SearchMaster @business = null        , @frn = null
 SearchMaster @business = 'something' , @frn = null
 SearchMaster @business = 'something' , @frn = 'something'
 SearchMaster @business = null        , @frn = 'something'
 SearchMaster @business = 'something' , @frn = 'something'
 SearchMaster @business = 'something' , @frn = ''
 SearchMaster @business = ''          , @frn = 'something'

请注意,最后 2 个不会返回任何内容 - 除非您在数据库中有空白业务和 frn ;)

如果您将来自 Marc 的 select 语句放在 AS 行之后,您的语句应该可以按预期工作。

所以是这样的:

CREATE PROCEDURE SearchMaster
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS
SELECT @business = NULLIF(@business,'') , @frn = NULLIF(@frn,'')

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)

并确保在您的数据源上设置 CancelSelectOnNullParameter="False"

【讨论】:

  • 只有倒数第二个没有返回任何东西,因为我没有空白的frn。我仍然对如何将 nullif 放在 AS 行之后感到有些困惑。你能提供一个使用我的sql的例子吗?
  • 另外,SearchMaster @business = '', @frn = 'something' 有效,但当我在代码中运行时无效。
  • 好的,我试试看告诉你
  • 好吧,那行得通。如果我在过程和代码中初始化@business = NULL 和@frn = NULL,为什么会这样做,我告诉它 ConvertEmptyStrings 为 null。另外,我不知道该给谁回答:你还是 Marc。
  • 好吧,我刚刚在文本框中输入了 frn 并将业务留空,即使通过执行 NULLIF 对存储过程进行了更改,它仍然无法正常工作。
猜你喜欢
  • 1970-01-01
  • 2020-12-24
  • 2016-04-22
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
相关资源
最近更新 更多