BUG: The Properties Collection Is Not Populated for Child Recordsets Associated with Chaptered ColumnsID: Q217890
|
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
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:
#include <COMDEF.H>
#include <oledb.h>
#undef EOF
#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;
}
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
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.
Additional query words: heirarchical
Keywords : kbADO kbADO200bug kbATL kbDatabase kbProvider
Version : WINDOWS:2.1
Platform : WINDOWS
Issue type : kbbug
Last Reviewed: March 11, 1999