Microsoft KB Archive/217890

= FIX: The Properties Collection Is Not Populated for Child Recordsets Associated with Chaptered Columns =

Article ID: 217890

Article Last Modified on 10/16/2002

-

APPLIES TO


 * Microsoft ActiveX Data Objects 2.1
 * Microsoft ActiveX Data Objects 2.1 Service Pack 1
 * Microsoft Data Access Components 2.1 Service Pack 2

-



This article was previously published under Q217890



SYMPTOMS
ADO Recordset objects returned from chaptered columns do not have their Properties collection populated. The Properties collection's Count property equal zero (0).

ADO extracts a child Recordset from a Hierarchical OLEDB provider by passing the value of the chaptered column to it. In the Visual Basic client code below, "rs.Fields(5)" is the chaptered column; the variable, numProps, is zero:

Dim rs As New ADODB.Recordset Dim rsChild As ADODB.Recordset Dim numProps As Integer rs.Open "c:\*.*", "Provider=ChildrsProv.CHildRSProv.1", adOpenForwardOnly, adLockOptimistic

Set rsChild = rs.Fields(5).Value numProps = rsChild.Properties.Count



RESOLUTION
This bug was corrected in MDAC 2.1 SP2.

To work around this bug, insert the following "GetProperty" C++ function as a method in a COM object. Essentially, the function returns the requested property of the underlying rowset using the OLE DB IDBProperties::GetPropertyInfo and IRowsetInfo::GetProperty methods. The parameters are:


 * pADORecordset- [in] IUnknown pointer to the Ado Recordset
 * bstrPropertyName - [in] Description of the Property ID**
 * pValue - [out] The property value


 * Refer to Appendix C in the OLE DB 2.0 Programmers Reference for a comprehensive list of Property ID descriptions.


 * 1) include 
 * 2) include 


 * 1) undef EOF
 * 2) import "c:\program files\common files\system\ado\msado15.dll" no_namespace

_COM_SMARTPTR_TYPEDEF(IRowset, __uuidof(IRowset)); _COM_SMARTPTR_TYPEDEF(IRowsetInfo, __uuidof(IRowsetInfo)); _COM_SMARTPTR_TYPEDEF(IDBProperties, __uuidof(IDBProperties)); _COM_SMARTPTR_TYPEDEF(IGetDataSource, __uuidof(IGetDataSource)); _COM_SMARTPTR_TYPEDEF(ICommand, __uuidof(ICommand));

STDMETHODIMP CPropertyHelper::GetProperty(IUnknown *pADORecordset, BSTR bstrPropertyName, VARIANT * pValue) {   HRESULT hr; ADORecordsetConstructionPtr pRC; ADOConnectionConstructionPtr pCC;

IRowsetPtr pRS; IRowsetInfoPtr pRI; IDBPropertiesPtr pDBProps; IGetDataSourcePtr pGetDataSource; ICommandPtr pCommand; // Make certain that we are getting an ADORecordset. pRC = pADORecordset;

// Get the IRowsetInfo interface. pRI = pRC->GetRowset;

// Get the property ID based on the name supplied. hr = pRI->GetSpecification(__uuidof(IGetDataSource), (IUnknown **)&pGetDataSource);

// The rowset was probably created with IOpenRowset::OpenRowset, // but just in case... if (pGetDataSource.GetInterfacePtr == NULL) {       // Need to get command first. hr = pRI->GetSpecification(__uuidof(ICommand), (IUnknown **)&pCommand); hr = pCommand->GetDBSession(__uuidof(IGetDataSource), (IUnknown **)&pGetDataSource); }   if(hr = pGetDataSource.GetInterfacePtr == NULL) return E_FAIL; hr = pGetDataSource->GetDataSource(__uuidof(IDBProperties), (IUnknown **)&pDBProps); // Want all of the rowset properties. DBPROPIDSET PropIDSet; PropIDSet.cPropertyIDs = 0; PropIDSet.guidPropertySet = DBPROPSET_ROWSETALL; PropIDSet.rgPropertyIDs = NULL;

DBPROPINFOSET * pPropertyInfoSet; ULONG ulPropInfoSets; OLECHAR * pDescBuffer; pDBProps->GetPropertyInfo(1,&PropIDSet, &ulPropInfoSets, &pPropertyInfoSet, &pDescBuffer); DBPROPID PropID; GUID guid; bool bFoundProperty = false; // Find the ID associated with the property name. for(ULONG ulIndex1= 0; ulIndex1 < ulPropInfoSets && bFoundProperty ==false; ulIndex1 ++) for (ULONG ulIndex = 0; ulIndex < pPropertyInfoSet[ulIndex1].cPropertyInfos; ulIndex++) {           if (_wcsicmp(pPropertyInfoSet[ulIndex1].rgPropertyInfos[ulIndex].pwszDescription, bstrPropertyName) == 0) {               PropID = pPropertyInfoSet[ulIndex1].rgPropertyInfos[ulIndex].dwPropertyID; guid = pPropertyInfoSet[ulIndex1].guidPropertySet; bFoundProperty = true; break; }   }

// Free structures. CoTaskMemFree(pDescBuffer); CoTaskMemFree(pPropertyInfoSet->rgPropertyInfos); CoTaskMemFree(pPropertyInfoSet);

if (bFoundProperty == false) return E_FAIL; // Might also want to call CreateErrorInfor/SetErrorInfo.

// Now use IRowsetInfo to return the property value. ULONG ulPropSets; DBPROPSET * prgPropSets; DBPROPIDSET rgPropertyIDSets;

rgPropertyIDSets.cPropertyIDs = 1; rgPropertyIDSets.guidPropertySet = guid; rgPropertyIDSets.rgPropertyIDs = &PropID;

hr = pRI->GetProperties(1, &rgPropertyIDSets, &ulPropSets, &prgPropSets);

// Copy the property value to the return VARIANT. VariantCopy(pValue, &prgPropSets->rgProperties->vValue); CoTaskMemFree(prgPropSets->rgProperties); CoTaskMemFree(prgPropSets); return S_OK; }

The following Visual Basic code accesses the "PropertyHelper.CPropertyHelper.1" COM object that contains the GetProperty method:

Dim rs As New ADODB.Recordset Dim rsChild As ADODB.Recordset rs.Open "c:\*.*", "Provider=ChildrsProv.CHildRSProv.1", adOpenForwardOnly, adLockOptimistic Set rsChild = rs.Fields(5).Value Dim obj Set obj = CreateObject("PropertyHelper.CPropertyHelper.1") Dim propVal As Variant obj.GetProperty rsChild, "IRowsetInfo", propVal Debug.Print propVal



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

This problem was corrected in MDAC 2.1 SP2.

Additional query words: heirarchical

Keywords: kbbug kbfix kbprovider kbado210sp2fix kbmdacnosweep KB217890

-

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

© Microsoft Corporation. All rights reserved.