【问题标题】:Populate gridview with results of a SQL Server stored procedure that returns multiple recordsets使用返回多个记录集的 SQL Server 存储过程的结果填充 gridview
【发布时间】:2012-08-20 13:33:16
【问题描述】:

我有一个返回多个记录集的存储过程。它可以是 1 个记录集、2 个记录集或更多。不知道有多少RS会回来。

在stackoverflow我找到了下面的示例

    Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("myConnection").ConnectionString)
    Dim cmd As New SqlCommand
    Dim Reader As SqlDataReader
    cmd.Connection = conn
    cmd.Parameters.AddWithValue("@ACTNbr", tbACTNbr.Text.ToString.Trim)
    cmd.Parameters.AddWithValue("@WTHNbr", tbWTHNbr.Text.ToString.Trim)
    cmd.CommandText = "sp_search_def"
    cmd.CommandType = CommandType.StoredProcedure
    conn.Open()
    Reader = cmd.ExecuteReader()
'The next part is what I found here at stackoverflow
While Reader.Read() OrElse (Reader.NextResult() And Reader.Read())
  For i As Integer = 0 To Reader.FieldCount - 1
    Response.Write(Reader(i).ToString())
    Response.Write(" ")
  Next
  Response.Write("<br />")
End While

上面的response.write 完美地显示了我需要的数据。但我需要将其放入 Gridview 中。即,我需要将存储过程的结果(及其所有结果集)放入一个 gridview 中。

我的网格视图设置为AutoGenerateColumns = "true"

我试过了:

myGridview.DataSource = Reader
myGridview.DataBind()

当然,我只得到其中一个记录集。

存储过程的结果都具有相同的格式 - 相同数量的列、标题等。

有人能指出我正确的方向吗?我一直在努力解决这个问题,但放弃了,现在我在这里问。

我是新手。

谢谢。

【问题讨论】:

  • 请将答案标记为正确。

标签: asp.net sql-server vb.net tsql stored-procedures


【解决方案1】:

使用 DataAdapter 填充 DataSet 而不是 DataReader,您可以轻松地绑定到您的 gridview,如下所示:

    Dim DS As DataSet
    Dim MyConnection As SqlConnection
    Dim MyDataAdapter As SqlDataAdapter

    'Create a connection to the SQL Server.
    MyConnection = New SqlConnection("server=(local);database=pubs;Trusted_Connection=yes")

    'Create a DataAdapter, and then provide the name of the stored procedure.
    MyDataAdapter = New SqlDataAdapter("GetAuthorsByLastName", MyConnection)

    'Set the command type as StoredProcedure.
    MyDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure

    'Create and add a parameter to Parameters collection for the stored procedure.
    MyDataAdapter.SelectCommand.Parameters.Add(New SqlParameter("@au_lname", _
   SqlDbType.VarChar, 40))

    'Assign the search value to the parameter.
    MyDataAdapter.SelectCommand.Parameters("@au_lname").Value = Trim(txtLastName.Text)

    'Create and add an output parameter to Parameters collection. 
    MyDataAdapter.SelectCommand.Parameters.Add(New SqlParameter("@RowCount", _
    SqlDbType.Int, 4))

    'Set the direction for the parameter. This parameter returns the Rows returned.
    MyDataAdapter.SelectCommand.Parameters("@RowCount").Direction = ParameterDirection.Output

    DS = New DataSet() 'Create a new DataSet to hold the records.
    MyDataAdapter.Fill(DS, "AuthorsByLastName") 'Fill the DataSet with the rows returned.

    'Get the number of rows returned, and then assign it to the Label control.
    'lblRowCount.Text = DS.Tables(0).Rows.Count().ToString() & " Rows Found!"
    lblRowCount.Text = MyDataAdapter.SelectCommand.Parameters(1).Value & " Rows Found!"

    'Set the data source for the DataGrid as the DataSet that holds the rows.
    Grdauthors.DataSource = DS.Tables("AuthorsByLastName").DefaultView

    'Bind the DataSet to the DataGrid. 
    'NOTE: If you do not call this method, the DataGrid is not displayed!
    Grdauthors.DataBind()

    MyDataAdapter.Dispose() 'Dispose of the DataAdapter.
    MyConnection.Close() 'Close the connection.

How to call SQL Server stored procedures in ASP.NET by using Visual Basic .NET

【讨论】:

    【解决方案2】:

    您只能将 GridView 绑定到一个结果集。例如,将GridView 绑定到包含多个DataTables 的DataSet 将只显示第一个 DataTable 中的数据。

    由于proc返回的所有结果集都具有相同的schema,因此需要将它们合并并将结果集绑定到GridView

    例子:

    //Assumes your proc returns a dataset with more than one datatable
    //Notice how all datables are merged into the first one [0]
    for (int i = 1; i < ds.Tables.Count; i++)
    {
        ds.Tables[0].Merge(ds.Tables[i]);  
    }
    
    grid.DataSource = ds;
    grid.DataBind();
    

    或者等价的:

    grid.DataSource = ds.Tables[0];//this DT has everything
    grid.DataBind();
    

    网格将显示所有数据表中的所有行

    当数据表有不同的架构时,合并的数据表将包含所有数据表中的所有列。

    例如,将一个DataTable 与一个名为Col1 的列与另一个DataTable 与一个名为Col2 的列合并将产生如下结果:

      +-----+------+
      |Col1 | Col2 |
      ------+------+
      |val1 |  null|
      +-----+------+
      |null |  val2|
      +-----+------+
    

    【讨论】:

      【解决方案3】:

      您需要绑定到 DataTable。一个 DataSet 可以包含多个表。

      DataSet.Tables Property

      【讨论】:

        【解决方案4】:

        使用@Kapil 和@Icarus 回复,我能够让它工作。 感谢您花时间提供帮助。它为我指明了正确的方向。

        这就是我最终的结果:

          Protected Sub btnSearch_Click(sender As Object, e As System.EventArgs)
            Dim DS As DataSet
            Dim MyConnection As SqlConnection
            Dim MyDataAdapter As SqlDataAdapter
            Dim msg As String = ""
        
            'Create a connection to the SQL Server.
            MyConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("msSQLdb").ConnectionString)
        
            'Create a DataAdapter, and then provide the name of the stored procedure.
            MyDataAdapter = New SqlDataAdapter("sp_search_all_SQLservers", MyConnection)
        
            'Set the command type as StoredProcedure.
            MyDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure
        
            'Create and add a parameter to Parameters collection for the stored procedure.
            MyDataAdapter.SelectCommand.Parameters.Add(New SqlParameter("@ACTNbr", SqlDbType.VarChar, 10))
            MyDataAdapter.SelectCommand.Parameters.Add(New SqlParameter("@WTHNbr", SqlDbType.VarChar, 15))
        
            'Assign the search value to the parameter.
            MyDataAdapter.SelectCommand.Parameters("@ACTNbr").Value = tbACTNbr.Text.ToString.Trim
            MyDataAdapter.SelectCommand.Parameters("@WTHNbr").Value = tbWTHNbr.Text.ToString.Trim
        
            'Create a new DataSet to hold the records.
            DS = New DataSet()
            'Fill the DataSet with the rows returned.
            MyDataAdapter.Fill(DS, "proc_results")
        
            'Set the data source for the gridview as the DataSet that holds the rows.
            gv.DataSource = DS.Tables("proc_results").DefaultView
            For i = 1 To DS.Tables.Count - 1
              DS.Tables(0).Merge(DS.Tables(i))
            Next
        
            msg = DS.Tables(0).Rows.Count & " rows found"
            gv.Caption = DS.Tables(0).Rows.Count & " rows found"
            gv.DataSource = DS
        
            'Bind the DataSet to the DataGrid. 
            'NOTE: If you do not call this method, the DataGrid is not displayed!    
            gv.DataBind()
            If gv.Rows.Count <> 0 Then
              gv.Visible = True
            Else
              msg = "No data found"
            End If
        
            MyDataAdapter.Dispose() 'Dispose of the DataAdapter.
            MyConnection.Close() 'Close the connection.
            DS.Dispose()
            lblMsg.Text = msg
          End Sub
        

        【讨论】:

          猜你喜欢
          • 2014-12-07
          • 1970-01-01
          • 1970-01-01
          • 2011-01-09
          • 1970-01-01
          • 2011-04-22
          • 1970-01-01
          • 2014-01-04
          相关资源
          最近更新 更多