【问题标题】:SqlDataSource and stored procedure call issueSqlDataSource 和存储过程调用问题
【发布时间】:2011-12-02 03:06:41
【问题描述】:

我偶然发现了一个问题,但我自己无法解决。希望有人能帮我解决。

所以,我在 SQL Server 2005 数据库中有一个简单的存储过程

CREATE PROCEDURE spTest
  @pin varchar(128)
AS
BEGIN
  SELECT @Pin as Param
END

以及一个在应用程序中带有SqlDataSourceGridView 控件的asp.net 页面(VS2008)

<asp:SqlDataSource 
  ID="sds2" 
  runat="server" 
  ConnectionString="..."
  SelectCommand="spTest"      
  SelectCommandType="StoredProcedure"
  >
  <SelectParameters>
    <asp:QueryStringParameter Name="pin" QueryStringField="pin" DbType="String"/>
  </SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="gv" runat="server" DataSourceID="sds2"></asp:GridView>

如您所见,代码很简单。不过,如果我不费心在 url 上指定 pin(.../Default.aspx 而不是 .../Default.aspx?pin=somevalue)或指定空行(.../Default.aspx?pin=),则不会调用存储过程(我使用 SQL Server 检查它探查器)。

此外,如果我用简单的替换 QueryStringParameter

<asp:Parameter Name="pin" DbType="String" />

并且不指出 DefaultValue 值,情况会重复,并且不会调用存储过程。这种行为的原因是什么?

我是 asp.net 的新手,可能会忽略一些东西,但我什至尝试在代码隐藏文件中以编程方式而不是声明方式执行相同操作,结果是相同的。我唯一能发现的是,在这种情况下,SqlDataSourceSelecting 事件会被触发,但Selected 不会。也许会发生某种错误?

无论如何,任何形式的帮助都将不胜感激。

【问题讨论】:

    标签: asp.net sql stored-procedures


    【解决方案1】:

    SqlDataSource 对象有一个名为@987654321@ 的属性。它的默认值为true,所以我认为您看到的行为是预期的,尽管并不明显。尝试将此属性设置为false

    <asp:SqlDataSource 
      ID="sds2" 
      runat="server" 
      ConnectionString="..."
      SelectCommand="spTest"      
      SelectCommandType="StoredProcedure"
      CancelSelectOnNullParameter="false"
      >
    

    此外,您可能会发现Parameter 类的@987654322@ 属性(QueryStringParameter 扩展了它)有一些用处,这取决于您存储的过程是否/如何处理null 值。它的默认值也是true

    【讨论】:

    • Jeremy,您将false 设置为CancelSelectOnNullParameter 的建议成功了!你是对的属性!非常感谢!默认设置的行为真的很奇怪......
    • 真正烦人的是 MS 文档中的“琐碎”示例似乎也没有提及这一点
    • 我认为它为我工作了很长时间。只是当我将我的项目移动到 4.5 时它停止了工作。
    【解决方案2】:

    试试这个。

    1. 创建一个方法,如果存储过程中没有传递参数,则返回 db null

      public static object GetDataValue(object o)
          {
              if (o == null || String.Empty.Equals(o))
                  return DBNull.Value;
              else
                  return o;
          }
      
    2. 创建一个调用存储过程并填充数据集的方法。

      公共数据集GetspTest(字符串引脚) {

          try
          {
              DataSet oDS = new DataSet();
              SqlParameter[] oParam = new SqlParameter[1];
      
      
              oParam[0] = new SqlParameter("@Pin", GetDataValue(pin));
      
              oDS = SqlHelper.ExecuteDataset(DataConnectionString, CommandType.StoredProcedure, "spTest", oParam);
              return oDS;
          }
          catch (Exception e)
          {
              ErrorMessage = e.Message;
              return null;
          }
      }
      
    3. 现在将数据集绑定到gridview

      private void GvTest()
      {
          DataSet oDsGvspTest = new DataSet();
                  string pin = Request.QueryString["Pin"];
              oDsGvspTest = GetspTest(pin);
                  if (oDsGvspTest.Tables[0].Rows.Count > 0)
                  {
                      Gv.DataSource = oDsGvspTest;
                      Gv.DataBind();
      
                  }
      
      }
      
    4. 现在在 page_load 事件中调用此方法

      if(!IsPostBack)
      {   
      GvTest();
      }
      

    如果觉得有用,请将其标记为您的答案,否则请告诉我...

    【讨论】:

    • 对不起 AnandMohanAwasthi,但我的问题是关于这种奇怪行为的原因,而不是可能的解决方法。
    • 可能是因为,sql server 不接受空值。为了成功执行过程,即使没有传递参数,您需要在存储过程中声明 Pin null 或传递 db.null。
    • 我忘了说你也需要修改查询。使用 COALESCE 函数。
    猜你喜欢
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多