OLE DB
consumers can use the ICommand family of interfaces that are exposed
by the Command object to execute SQL statements. The most common
interfaces are ICommand and ICommandText. The following C++ code shows
how this task is done. In the sample code, the first two statements
return
NULL
for the pointer to the
rowset because no rowset is created. The third statement creates a
rowset and returns a pointer to its IUnknown interface.
#include atlbase.h
#include comdef.h
#include comutil.h
#include oledb.h
#include atldbcli.h
#include <iostream>
#include <iomanip>
using std::cout;
using std::hex;
using std::setw;
using std::setfill;
using std::right;
using std::endl;
#define FAIL_IF( hr ) issue_if_failed( __FILE__, __LINE__, hr )
inline void issue_if_failed( char* file, ULONG line, HRESULT hr )
{
/* This method throws an error if hr is a failure. */
if( FAILED( hr ) )
{
ATLTRACE( %s(%d): Failure 0x%X\n, (char*)file, line, hr );
_com_issue_error( hr );
}
}
HRESULT InstantiateProvider( CComPtr<IUnknown>& spUnkDataSrc )
{
/* spUnkDataSrc contains a NULL IUnknown pointer. */
/* This method instantiates the IOM Provider Data Source object and */
/* stores a pointer to its IUnknown interface in spUnkDataSrc. */
CLSID clsid;
FAIL_IF( CLSIDFromProgID( L"SAS.IOMProvider", &clsid ) );
FAIL_IF( CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&spUnkDataSrc ) );
return S_OK;
}
HRESULT InitializeProvider( CComPtr<IUnknown>& spUnkDataSrc )
{
/* spUnkDataSrc contains an IUnknown pointer to an uninitialized IOM Data Source Object. */
/* This method initializes the IOM Provider specifically. Initializing the SAS/SHARE */
/* Provider requires different properties as described in Establishing an ADO Connection. */
CComQIPtr<IDBInitialize> spInit = spUnkDataSrc;
CComQIPtr<IDBProperties> spProp = spUnkDataSrc;
if( spInit == NULL || spProp == NULL )
return E_FAIL;
CDBPropSet Props( DBPROPSET_DBINIT );
Props.AddProperty( DBPROP_INIT_DATASOURCE, (WCHAR*)L_LOCAL_ );
FAIL_IF( spProp->SetProperties( 1, &Props ) );
FAIL_IF( spInit->Initialize() );
return S_OK;
}
HRESULT CreateSession( CComPtr<IUnknown>& spUnkDataSrc, CComPtr<IUnknown>& spUnkSession )
{
/* spUnkDataSrc contains a pointer to the IUnknown interface of an initialized Data Source Object */
/* spUnkSession is the location for a pointer to the IUnknown interface of the newly created Session Object */
HRESULT hr = E_FAIL;
CComQIPtr<IDBCreateSession> spCreateSession = spUnkDataSrc;
if( spCreateSession == NULL )
cout << "ERROR: IDBCreateSession not found" << endl;
else
{
hr = spCreateSession->CreateSession( NULL, IID_IUnknown, &spUnkSession.p );
FAIL_IF( hr );
}
return hr;
}
HRESULT CreateCommand( CComPtr<IUnknown>& spUnkSession, CComPtr<IUnknown>& spUnkCommand )
{
/* spUnkSession contains a pointer to the IUnknown interface of an open Session Object */
/* spUnkCommand is the location for a pointer to the IUnknown interface of the newly created Command Object */
HRESULT hr = E_FAIL;
CComQIPtr<IDBCreateCommand> spCreateCommand = spUnkSession;
if( spCreateCommand == NULL )
cout << "ERROR: IDBCreateCommand not found" << endl;
{
hr = spCreateCommand->CreateCommand( NULL, IID_IUnknown, &spUnkCommand.p );
FAIL_IF( hr );
}
return hr;
}
HRESULT ExecuteSQL( CComPtr<IUnknown>& spUnkCommand, bstr_t bstrSQL, CComPtr<IUnknown>& spUnkRowset )
{
/* spUnkCommand contains a pointer to the IUnknown interface of an open command */
/* spUnkRowset is where the IUknown pointer to the created rowset (if any) will be stored */
HRESULT hr = E_FAIL;
CComQIPtr<ICommandText> spCommandText = spUnkCommand;
if( spCommandText == NULL )
cout << "ERROR: ICommandText not found" << endl;
else
{
FAIL_IF( spCommandText->SetCommandText( DBGUID_DBSQL, bstrSQL ) );
hr = spCommandText->Execute( NULL, IID_IUnknown, NULL, NULL, &spUnkRowset.p );
FAIL_IF( hr );
}
return hr;
}
int main(int argc, char* argv[])
{
CoInitialize(NULL);
try
{
HRESULT hr = E_FAIL;
CComPtr<IUnknown> spUnkDataSrc = NULL; /* pointer to IUnknown interface of a Data Source Object */
CComPtr<IUnknown> spUnkSession = NULL; /* pointer to IUnknown interface of a Session Object */
CComPtr<IUnknown> spUnkCommand = NULL; /* pointer to IUnknown interface of a Command Object */
CComPtr<IUnknown> spUnkRowset = NULL; /* pointer to IUnknown interface of a Rowset Object */
FAIL_IF( InstantiateProvider( spUnkDataSrc ) ); /* creates an instance of the IOM Provider Data Source */
FAIL_IF( InitializeProvider( spUnkDataSrc ) ); /* initializes the Data Source object to
connect to the local workspace server */
FAIL_IF( CreateSession( spUnkDataSrc, spUnkSession ) ); /* creates an instance of a Session Object */
FAIL_IF( CreateCommand( spUnkSession, spUnkCommand ) ); /* creates an instance of a Command Object */
/* create a new data set */
FAIL_IF( ExecuteSQL( spUnkCommand, "create table sasuser.newtable ( i num, name char(40), age num );",
spUnkRowset ) );
/* add some rows to the new data set */
FAIL_IF( ExecuteSQL( spUnkCommand, "insert into sasuser.newtable values( 0, \"Bill\", 32 )
values( 1, \"John\", 99 );", spUnkRowset ) );
/* open a Recordset on the new data set */
FAIL_IF( ExecuteSQL( spUnkCommand, "select * from sasuser.newtable", spUnkRowset ) );
/* do something with spUnkRowset */
/* ... */
}
catch( _com_error& e )
{
cout << "ERROR: 0x" << hex << setw(8) << setfill('0') << right << e.Error() << endl;
}
CoUninitialize();
return 0;
}