MDAC 2.5 SDK - OLE DB Providers
OLE DB Provider for SQL Server
To fetch rows from a result set
/*
Example shows how to fetch rows from a result set.
*/
void InitializeAndEstablishConnection();
void ProcessResultSet();
#define UNICODE
#define _UNICODE
#define DBINITCONSTANTS
#define INITGUID
#include <stdio.h>
#include <tchar.h>
#include <stddef.h>
#include <windows.h>
#include <iostream.h>
#include <oledb.h>
#include <SQLOLEDB.h>
IDBInitialize* pIDBInitialize = NULL;
IDBProperties* pIDBProperties = NULL;
IDBCreateSession* pIDBCreateSession = NULL;
IDBCreateCommand* pIDBCreateCommand = NULL;
ICommandText* pICommandText = NULL;
IRowset* pIRowset = NULL;
IColumnsInfo* pIColumnsInfo = NULL;
DBCOLUMNINFO* pDBColumnInfo = NULL;
IAccessor* pIAccessor = NULL;
DBPROP InitProperties[4];
DBPROPSET rgInitPropSet[1];
ULONG i, j;
HRESULT hr;
LONG cNumRows = 0;
ULONG lNumCols;
WCHAR* pStringsBuffer;
DBBINDING* pBindings;
ULONG ConsumerBufColOffset = 0;
HACCESSOR hAccessor;
ULONG lNumRowsRetrieved;
HROW hRows[10];
HROW* pRows = &hRows[0];
BYTE* pBuffer;
void main() {
// Here is the command to execute.
WCHAR* wCmdString
= OLESTR(" SELECT title, price FROM titles WHERE royalty > 14");
// Call a function to initialize and establish connection.
InitializeAndEstablishConnection();
// Create a session object.
if(FAILED(pIDBInitialize->QueryInterface(
IID_IDBCreateSession, (void**) &pIDBCreateSession)))
{
cout << "Failed to obtain IDBCreateSession interface.\n";
}
if(FAILED(pIDBCreateSession->CreateSession(
NULL, IID_IDBCreateCommand, (IUnknown**) &pIDBCreateCommand)))
{
cout << "pIDBCreateSession->CreateSession failed.\n";
}
// Access the ICommandText interface.
if(FAILED(pIDBCreateCommand->CreateCommand(
NULL, IID_ICommandText, (IUnknown**) &pICommandText)))
{
cout << "Failed to access ICommand interface.\n";
}
// Use SetCommandText() to specify the command text.
if(FAILED(pICommandText->SetCommandText(DBGUID_DBSQL, wCmdString)))
{
cout << "Failed to set command text.\n";
}
// Execute the command.
if(FAILED(hr = pICommandText->Execute(NULL,
IID_IRowset, NULL, &cNumRows, (IUnknown **) &pIRowset)))
{
cout << "Failed to execute command.\n";
}
// Process the result set.
ProcessResultSet();
pIRowset->Release();
// Free up memory.
pICommandText->Release();
pIDBCreateCommand->Release();
pIDBCreateSession->Release();
if(FAILED(pIDBInitialize->Uninitialize()))
{
/* Uninitialize is not required, but it fails if an interface
has not been released. This can be used for debugging.
cout << "Problem uninitializing.\n"; */
} // End if.
pIDBInitialize->Release();
// Release the COM library.
CoUninitialize();
};
//--------------------------------------------------------------------
void InitializeAndEstablishConnection()
{
// Initialize the COM library.
CoInitialize(NULL);
// Obtain access to the SQLOLEDB provider.
hr = CoCreateInstance(CLSID_SQLOLEDB, NULL,
CLSCTX_INPROC_SERVER,
IID_IDBInitialize,
(void **) &pIDBInitialize);
if(FAILED(hr))
{
printf("Failed to get IDBInitialize interface.\n");
} // End if.
/* Initialize the property values needed
to establish the connection. */
for(i = 0; i < 4; i++)
VariantInit(&InitProperties[i].vValue);
// Server name.
InitProperties[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
InitProperties[0].vValue.vt = VT_BSTR;
InitProperties[0].vValue.bstrVal = SysAllocString(L"server");
InitProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[0].colid = DB_NULLID;
// Database.
InitProperties[1].dwPropertyID = DBPROP_INIT_CATALOG;
InitProperties[1].vValue.vt = VT_BSTR;
InitProperties[1].vValue.bstrVal = SysAllocString(L"database");
InitProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[1].colid = DB_NULLID;
// Username (login).
InitProperties[2].dwPropertyID = DBPROP_AUTH_USERID;
InitProperties[2].vValue.vt = VT_BSTR;
InitProperties[2].vValue.bstrVal = SysAllocString(L"login");
InitProperties[2].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[2].colid = DB_NULLID;
// Password.
InitProperties[3].dwPropertyID = DBPROP_AUTH_PASSWORD;
InitProperties[3].vValue.vt = VT_BSTR;
InitProperties[3].vValue.bstrVal = SysAllocString(L"Password");
InitProperties[3].dwOptions = DBPROPOPTIONS_REQUIRED;
InitProperties[3].colid = DB_NULLID;
/*
Now that the properties are set, construct the DBPROPSET structure
(rgInitPropSet). The DBPROPSET structure is used to pass an array
of DBPROP structures (InitProperties) to the SetProperties method.
*/
rgInitPropSet[0].guidPropertySet = DBPROPSET_DBINIT;
rgInitPropSet[0].cProperties = 4;
rgInitPropSet[0].rgProperties = InitProperties;
// Set initialization properties.
hr = pIDBInitialize->QueryInterface(IID_IDBProperties,
(void **)&pIDBProperties);
if(FAILED(hr))
{
cout << "Failed to get IDBProperties interface.\n";
}
hr = pIDBProperties->SetProperties(1, rgInitPropSet);
if(FAILED(hr))
{
cout << "Failed to set initialization properties.\n";
} // End if.
pIDBProperties->Release();
// Now establish the connection to the data source.
if(FAILED(pIDBInitialize->Initialize()))
{
cout << "Problem in establishing connection to the data
source.\n";
}
} // End of InitializeAndEstablishConnection.
//--------------------------------------------------------------------
// Retrieve and display data resulting from a query.
void ProcessResultSet()
{
// Obtain access to the IColumnInfo interface, from the Rowset
// object.
hr = pIRowset->QueryInterface(IID_IColumnsInfo,
(void **)&pIColumnsInfo);
if(FAILED(hr))
{
cout << "Failed to get IColumnsInfo interface.\n";
} // End if.
// Retrieve the column information.
pIColumnsInfo->GetColumnInfo(&lNumCols, &pDBColumnInfo,
&pStringsBuffer);
// Free the column information interface.
pIColumnsInfo->Release();
// Create a DBBINDING array.
pBindings = new DBBINDING[lNumCols];
// Using the ColumnInfo structure, fill out the pBindings array.
for(j=0; j<lNumCols; j++)
{
pBindings[j].iOrdinal = j+1;
pBindings[j].obValue = ConsumerBufColOffset;
pBindings[j].pTypeInfo = NULL;
pBindings[j].pObject = NULL;
pBindings[j].pBindExt = NULL;
pBindings[j].dwPart = DBPART_VALUE;
pBindings[j].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
pBindings[j].eParamIO = DBPARAMIO_NOTPARAM;
pBindings[j].cbMaxLen = pDBColumnInfo[j].ulColumnSize;
pBindings[j].dwFlags = 0;
pBindings[j].wType = pDBColumnInfo[j].wType;
pBindings[j].bPrecision = pDBColumnInfo[j].bPrecision;
pBindings[j].bScale = pDBColumnInfo[j].bScale;
// Compute the next buffer offset.
ConsumerBufColOffset = ConsumerBufColOffset +
pDBColumnInfo[j].ulColumnSize;
};
// Get the IAccessor interface.
hr = pIRowset->QueryInterface(IID_IAccessor, (void **) &pIAccessor);
if(FAILED(hr))
{
cout << "Failed to obtain IAccessor interface.\n";
}
// Create an accessor from the set of bindings (pBindings).
pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, lNumCols,
pBindings, 0, &hAccessor, NULL);
// Print column names.
for(j=0; j<lNumCols; j++)
{
printf("%-40S", pDBColumnInfo[j].pwszName);
};
// Get a set of 10 rows.
pIRowset->GetNextRows(NULL, 0, 10, &lNumRowsRetrieved,
&pRows);
// Allocate space for the row buffer.
pBuffer = new BYTE[ConsumerBufColOffset];
// Display the rows.
while(lNumRowsRetrieved > 0)
{
// For each row, print the column data.
for(j=0; j<lNumRowsRetrieved; j++)
{
// Clear the buffer.
memset(pBuffer, 0, ConsumerBufColOffset);
// Get the row data values.
pIRowset->GetData(hRows[j], hAccessor, pBuffer);
// Print title and price values.
printf("%-40s%f\n", &pBuffer[pBindings[0].obValue],
(FLOAT) pBuffer[pBindings[0].obValue]);
}; // for.
// Release the rows retrieved.
pIRowset->ReleaseRows(lNumRowsRetrieved, hRows,
NULL, NULL, NULL);
// Get the next set of 10 rows.
pIRowset->GetNextRows(NULL, 0, 10, &lNumRowsRetrieved,
&pRows);
}; // while lNumRowsRetrieved > 0.
// Free up all allocated memory.
delete [] pBuffer;
pIAccessor->ReleaseAccessor(hAccessor, NULL);
pIAccessor->Release();
delete [] pBindings;
} // ProcessResultSet.