Using the dbDAO GetRowsEx Method

The GetRowsEx method retrieves multiple records and enables you to specify the data types of the fields stored in your application variables. It has the following parameters.

Parameter Data type Description
pvBuffer LPVOID Pointer to the buffer in which to store returned records.
CbRow LONG Length of the record, in bytes.
Prb LPDAORSETBINDING Pointer to the binding structure (see the following description).
Cbinding LONG Number of bindings.
PvVarBuffer LPVOID Pointer to the buffer in which to store variable-length data.
CbVarBuffer LONG Length, in bytes, of pvVarBuffer.
Lrows LONG Number of records requested.

The DAORSETBINDING structure specifies how data is to be copied from the records to the memory buffer. A separate binding structure must be filled in for each field retrieved. DAORSETBINDING is defined as follows:

typedef struct
	{
	DWORD   dwBindIndexType;
	union
		{
		LONG    i;
		LPCTSTR pstr;
		};

	DWORD   dwType;
	DWORD   dwOffset;
	DWORD   cb;

	} DAORSETBINDING, *LPDAORSETBINDING;

The DAORSETBINDING structure has the following members.

Member Description
dwBindIndexType Value specifying whether a field is indicated by an index number or by name. This member is one of the following values:

dbBindIndexINT (index)
dbBindIndexSTR (name)

dwType Data type. This member is one of the following values:

dbBindI2 (long)
dbBindI4 (short)
dbBindR4 (float)
dbBindR8 (double)
dbBindCY (currency)
dbBindDATE (DATE)
dbBindBOOL (VARIANT_BOOL)
dbBindUI1 (unsigned char)
dbBindVARIANT (VARIANT)
dbBindWCHAR (wchar_t[])
dbBindSTRING (same as dbBindWCHAR for Unicode,
dbBindUI1 for ANSI)
dbBindLPSTR (char_pointer)
dbBindLPTSTR (wchar_pointer)
dbBindLPSTRING (dbBindLPTSTR for Unicode,
dbBindLPSTR for ANSI)
dbBindBookmark (CdbBookmark)
dbBindBlob (unsigned char pointer)

dwOffset Offset, in bytes, in the record buffer where the data is copied.
Cb Field length, in bytes.

The following code from the GetRows example shows how to use the GetRowsEx method. Note that the table schema is known a priori, allowing you to predefine a structure for the data.

Two different binding schemes for retrieving string data are shown. If the size of the string is fixed, you can retrieve the strings directly into the structure. If you are using variable-length strings, they will be placed sequentially in a single large buffer, and a pointer into that buffer will be stored in the structure.

// Structure for GetRowsEx:
typedef struct
	{
	LONG	lEmpId;
	TCHAR	*strLastName;
	TCHAR	strFirstName[20];
	} EMP, *LPEMP ;

// Employee table binding: 
DAORSETBINDING	Bindings[] = 
{
//Index Type		Column		Type			Offset						Size
{dbBindIndexINT,	EMP_ID,		dbBindI4,		offsetof(EMP,lEmpId),		sizeof(LONG)},
{dbBindIndexINT,	EMP_LNAME,	dbBindLPSTRING,	offsetof(EMP,strLastName),	sizeof(TCHAR *)},
{dbBindIndexINT,	EMP_FNAME,	dbBindSTRING,	offsetof(EMP,strFirstName),	sizeof(TCHAR) * 20}
};

// Perform C++ GetRowsEx against the Employee table.
void CGetRowsDlg::DoGetRowsEx() 
{
	LPEMP			pEmpRows = new EMP[MAX_EMP_REC];
	CListBox		*pListBox = (CListBox *)GetDlgItem(IDD_GETROWSLISTEX);
	CString			strLBRow;
	TCHAR			szId[16];
	LONG			lNumRecords;
	LONG			lCount;
	TCHAR			pBuf[MAX_EMP_REC * 15];		// Allow average of 15 chars/name.

	//Perform GetRows on Employee table.
	//This GetRows uses a specific C++ structure.
	try
		{
		lNumRecords = m_cEmpRecordSet.GetRowsEx(pEmpRows, sizeof(EMP),
									&Bindings[0], sizeof(Bindings) / sizeof(DAORSETBINDING),
									pBuf, sizeof(pBuf),
									MAX_EMP_REC); //arbitrarily get MAX_EMP_REC rows
		}
	catch (CdbException e)
		{
		//Differentiate between GetRowsEx Errors and other CdbExceptions.
		//See defines in DAOGETRW.H.
		if(	e.m_hr == E_ROWTOOSHORT ||
			e.m_hr == E_BADBINDINFO ||			
			e.m_hr == E_COLUMNUNAVAILABLE )
			{
			AfxMessageBox(_T("Error in GetRowsEx call."));
			}	
		else
			{
			AfxMessageBox(_T("General CdbException"));
			}
		delete [] pEmpRows;
		return;
		}


	//Step through the returned rows. 
	for (lCount = 0; lCount < lNumRecords; lCount++)
		{
		strLBRow.Empty();
		wsprintf(szId, _T("%d,  "), pEmpRows[lCount].lEmpId);
		strLBRow += szId;
		strLBRow += pEmpRows[lCount].strLastName;
		strLBRow += _T(", ");
		strLBRow += (LPCTSTR) pEmpRows[lCount].strFirstName;
		pListBox->AddString(strLBRow);
		}

	delete [] pEmpRows;
}