Results 1 to 7 of 7

Thread: Generating one recordset from another (output of stored proc)

  1. #1

    Thread Starter
    PowerPoster BruceG's Avatar
    Join Date
    May 2000
    Location
    New Jersey (USA)
    Posts
    2,657

    Generating one recordset from another (output of stored proc)

    Hello all,
    I have a "SELECT" stored procedure which returns a recordset consisting of about 20 fields. After calling the sp, I use the recordset to populate listview. All of this works fine.
    The pertinent code is basically:

    Code:
    Dim strSQL As String
    strSQL = "sp_MyStoredProc ... "
    Set rtemp = OpenRecordset(strSQL, adOpenStatic, adLockReadOnly)
    While Not rtemp.EOF
        ' populate listview item
        rtemp.MoveNext
    Wend
    What I'd like to do now is create a "summary" version of my process, which would conceptually consist of using the "rTemp" recordset as if it was a table, where I could either use it in the VB6 program, or create another sp that calls the original sp and processes the origninal sp's resultset.
    Conceptually:
    "SELECT col1, col2, sum(col3) as the_total FROM rtemp GROUP BY col1, col2"

    What are my options for this, if either scenario is possible?

    (I know I could write an alternative "summary" version of the original sp, however, all the "hard work" in generating the detailed result recordset is done in the original sp, and I would prefer not to have to duplicate my efforts as well as maintain the code in two places should the general requirements of the detail query change.)
    "It's cold gin time again ..."

    Check out my website here.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Generating one recordset from another (output of stored proc)

    That kind of magic is possible with the COM-wrapper for SQLite (vbRichClient5 or RC6),
    since it supports not only InMemory-DBs, but also appropriate loading-functions for ADO-Rs.

    Here is fully working example-code, which needs:
    - a reference to either vbRichClient5 or RC6
    - a reference to ADO (2.5 or 2.6 is enough)
    - a component-reference to the MS Hierarchical FlexGrid
    - a roughly placed instance of the above Grid on your Form under its default-name

    Code:
    Option Explicit
    
    Private MemDB As cMemDB
    
    Private Sub Form_Load()
      Set MemDB = New_c.MemDB
    End Sub
     
    Private Sub Form_Click()
      MemDB.Cnn.CreateTableFromADORs MemDB.Cnn, "T1", NewDemoRs
      
      Dim AdoRs As ADODB.Recordset
      Set AdoRs = MemDB.GetRs("Select Col1,Col2,Sum(Col3) From T1 Group By Col1,Col2").GetADORsFromContent
      Set MSHFlexGrid1.DataSource = AdoRs
    End Sub
    The part I've marked blue above, is a function which returns a DemoRs (which you could exchange to your real one).
    Here is the code for it (to be placed in the same Form)

    Code:
    Private Function NewDemoRs() As ADODB.Recordset
      Set NewDemoRs = New ADODB.Recordset
          NewDemoRs.Fields.Append "Col1", vbLong
          NewDemoRs.Fields.Append "Col2", vbString
          NewDemoRs.Fields.Append "Col3", vbLong
      NewDemoRs.Open
      
      'now we insert a few records, forming 4 "Groups"
      NewDemoRs.AddNew Array(0, 1, 2), Array(1, "A", 1)
      NewDemoRs.AddNew Array(0, 1, 2), Array(1, "A", 1)
      
      NewDemoRs.AddNew Array(0, 1, 2), Array(1, "B", 2)
      NewDemoRs.AddNew Array(0, 1, 2), Array(1, "B", 2)
      
      NewDemoRs.AddNew Array(0, 1, 2), Array(2, "C", 3)
      
      NewDemoRs.AddNew Array(0, 1, 2), Array(3, "D", 4)
    End Function
    Such a MemDB-approach allows you to insert more than a single Table of course -
    so that you can perform even complex clientside Joins across several "parked Rs-Tables" there.

    HTH

    Olaf

  3. #3

    Thread Starter
    PowerPoster BruceG's Avatar
    Join Date
    May 2000
    Location
    New Jersey (USA)
    Posts
    2,657

    Re: Generating one recordset from another (output of stored proc)

    Thanks - interesting - will take this under advisement ...
    "It's cold gin time again ..."

    Check out my website here.

  4. #4
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Generating one recordset from another (output of stored proc)

    Back in the 1970s we got a thing in SQL called a subquery. Many dialects of SQL that support stored procedures allow calls to them to be used as subqueries.

  5. #5

    Thread Starter
    PowerPoster BruceG's Avatar
    Join Date
    May 2000
    Location
    New Jersey (USA)
    Posts
    2,657

    Re: Generating one recordset from another (output of stored proc)

    Thanks dilettante - I am well aware of subqueries - using SQL Server here (an older version), I do not believe SQL Server supports what you are suggesting here (if wrong, I am all ears ...)
    "It's cold gin time again ..."

    Check out my website here.

  6. #6
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Generating one recordset from another (output of stored proc)

    I was pretty sure you could as long as the stored procedure is written as a table-valued function.

    Another option might be to query it into a temporary table.

    Or you could write a custom aggregator class, e.g.:

    Code:
    Option Explicit
    
    Private Groups As ADODB.Recordset
    Private Names As Variant
    
    Public Sub Aggregate(ByVal RS As ADODB.Recordset)
        Dim newf1 As ADODB.Field 'Optimize access.
        Dim newf2 As ADODB.Field
        Dim newf3 As ADODB.Field
        Dim f1 As ADODB.Field 'Optimize access.
        Dim f2 As ADODB.Field
        Dim fS3 As ADODB.Field
    
        With RS
            With .Fields
                Set newf1 = .Item("col1")
                Set newf2 = .Item("col2")
                Set newf3 = .Item("col3")
            End With
            If Not Groups Is Nothing Then Groups.Close
            Set Groups = New ADODB.Recordset
            With Groups
                .CursorLocation = adUseClient
                With .Fields
                    .Append "col1", adBoolean
                    .Append "col2", adInteger
                    .Append "SUM(col3)", adInteger
                    Groups.Open 'Makes the appended fields valid.
                    Set f1 = .Item("col1")
                    Set f2 = .Item("col2")
                    Set fS3 = .Item("SUM(col3)")
                End With
                f1.Properties.Item("Optimize").Value = True 'Creates a temporary index.
                f2.Properties.Item("Optimize").Value = True
                'Aggregate:
                Do Until RS.EOF
                    'Group by col1, col2 (using a hack because newf1.Type = adSmallInt, not adBoolean):
                    .Filter = "col1=#" _
                            & CStr(CBool(newf1.Value)) _
                            & "# AND col2=" _
                            & CStr(newf2.Value)
                    If .EOF Then
                        'Add new group:
                        .AddNew Names, Array(newf1.Value, newf2.Value, newf3.Value)
                    Else
                        'Sum new f3/col3 value:
                        fS3.Value = fS3.Value + newf3.Value
                    End If
                    RS.MoveNext
                Loop
                .Filter = adFilterNone
            End With
            .MoveFirst
        End With
    End Sub
    
    Public Property Get Recordset() As ADODB.Recordset
        Set Recordset = Groups
    End Property
    
    Private Sub Class_Initialize()
        Names = Array("col1", "col2", "SUM(col3)")
    End Sub
    
    Private Sub Class_Terminate()
        Groups.Close
    End Sub
    See the comments. A bit of fudging is going on here because of a bug/limitation in the MS Jet SQL Expression Service related to Boolean expressions.
    Attached Files Attached Files

  7. #7
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Generating one recordset from another (output of stored proc)

    Its been a while, but yes, you can exec an sproc into a temp table (does not need to be a TVF)... I forget the exact syntax, but it is possible. The other options is also to simply do it client-side, as olaf & Dil have shown. All of which are perfectly viable options. Just depends on which method you're more comfortable with.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width