Microsoft KB Archive/202912

= PRB: Cannot Create ADO Recordset Hierarchies Manually =

Article ID: 202912

Article Last Modified on 8/23/2001

-

APPLIES TO


 * Microsoft ActiveX Data Objects 2.0
 * Microsoft ActiveX Data Objects 2.1
 * Microsoft ActiveX Data Objects 2.5
 * Microsoft ActiveX Data Objects 2.6
 * Microsoft ActiveX Data Objects 2.7

-



This article was previously published under Q202912



SYMPTOMS
With Microsoft ActiveX Data Objects, you can programmatically create recordsets in memory using the Recordset.Fields.Append method. With the Recordset.Fields.Append method, you can create a field of type adChapter, adDispatch, adVariant, or adUnknown, and then later insert another manually created recordset into this field. This method can be used to manually create a hierarchical (or nested) recordset that appears to work in the same manner as a nested recordset returned by the SHAPE provider. This functionality appears to work properly but is actually not supported by ADO.



CAUSE
The recordset object stored inside of the field is stored as a IDispatch or IUnknown pointer, which works properly in an in-process COM environment. For example, an ADO recordset created in this manner cannot be marshalled over DCOM or HTTP with RDS because ADO does not provide functionality to marshal the internal IDispatch / IUnknown pointers stored inside of the fields. Also, if you close the master recordset without looping through each record and each field and explicitly release each nested recordset, you will leak the memory associated with the child recordset.



STATUS
This behavior is by design. ADO does not support the creation of recordsets in this manner. ADO does not offer marshalling support for the internal recordset pointers. Use of the adChapter, adDispatch, adVariant, and adUnknown fields created using the Recordset.Fields.Append method is not supported by ADO and can result in leaked memory and leaked interface pointers even when used in process.



MORE INFORMATION
The following sample requires advanced knowledge of Remote Data Services (RDS) and ActiveX Data Objects (ADO) programming:  Build a Visual Basic COM DLL with the sample code provided. Make a note of the ProgID of the Visual Basic COM Object (ProgID is "Project Name.Class Name" ).  Add the RDS required ADCLaunch key under:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Parameters\ADCLaunch

For additional information about RDS Registry/Security Settings, please see the following article in the Microsoft Knowledge Base:

191741 INFO: RDS Registry/Security Settings For Custom Business Objects

 Run client code from Visual Basic and uncomment one of the three CreateObject calls.

RESULT: Recordset works properly in-process but fails when used with RDS over HTTP and over DCOM. ' Start VB COM DLL code Function getRS1 As ADODB.Recordset Dim rsParent As New ADODB.Recordset Dim rsChild As New ADODB.Recordset

rsParent.CursorLocation = adUseClient rsChild.CursorLocation = adUseClient ' Add fields to recordsets. rsParent.Fields.Append "ParentName", adVarChar, 20 rsParent.Fields.Append "ChildRS", adIDispatch rsChild.Fields.Append "ChildName", adVarChar, 20 ' Open recordsets rsParent.Open rsChild.Open ' Add records to child recordset. rsChild.AddNew rsChild(0) = "Child1" rsChild.Update rsChild.AddNew rsChild(0) = "Child2" rsChild.Update rsChild.MoveFirst ' Add record to parent recordset. rsParent.AddNew rsParent(0) = "Parent1" rsParent(1) = rsChild rsParent.Update rsParent.MoveFirst Set getRS1 = rsParent

End Function ' End VB COM DLL code

' Start VB client code Private Sub Command1_Click Dim ds As New RDS.DataSpace Dim rs As New ADODB.Recordset Dim objTestHR As Object

' UN-COMMENT ONE OF THE FOLLOWING 3 CREATEOBJECT LINES. ' USE THE PROGID FOR THE VB COM DLL CREATED IN STEP 1.

' HTTP METHOD: 'Set objTestHR = ds.CreateObject( "MyProject.MyClass", _                    '"http://servername" )

' DCOM METHOD: 'Set objTestHR = ds.CreateObject( "MyProject.MyClass", _                    '"\\servername" )

' IN-PROC METHOD: 'Set objTestHR = CreateObject("MyProject.MyClass") Set rs = objTestHR.getRS1 Debug.Print "getRS1 results:" Debug.Print ">>" & rs.Fields(0).Value Debug.Print ">>>>" & rs.Fields(1).Value.Fields(0).Value rs.Fields(1).Value.MoveNext Debug.Print ">>>>" & rs.Fields(1).Value.Fields(0).Value rs.Close Set rs = Nothing End Sub ' End VB client code

Keywords: kbdatabase kbprb KB202912

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.