OLE DB
consumers can use the ITableDefinition interface that is exposed by
the Session object to create and delete data sets. The following
C++ code shows how this task is done.
The code
uses the IOM provider to create and delete a table named
newtable
in the
sasuser
library.
The sample first creates the table with three columns: a numeric column
named
i
, a character column of length 40
named
name
, and a numeric column named
age
. The code then deletes that same table.
#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 Data Provider. */
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 where a pointer to the IUnknown interface of the newly created
Session Object will be stored */
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 CreateNewTable( CComPtr<IUnknown>& spUnkSession )
{
/* spUnkSession contains a pointer to the IUnknown interface of an open Session Object */
/* This method creates a table named newtable from the sasuser library */
HRESULT hr = E_FAIL;
CComQIPtr<ITableDefinition> spTableDef = spUnkSession;
if( spTableDef == NULL )
cout << "ERROR: ITableDefinition not found" << endl;
else
{
CComPtr<IUnknown> spUnkNewTable = NULL;
DBORDINAL cColumnDescs = 3;
DBCOLUMNDESC rgColumnDescs[3];
DBID in_table;
in_table.eKind = DBKIND_NAME; /* only DBKIND_NAME supported */
in_table.uName.pwszName = L"sasuser.newtable";
memset( rgColumnDescs, 0, 3*sizeof(DBCOLUMNDESC) );
rgColumnDescs[0].wType = DBTYPE_R8;
rgColumnDescs[0].ulColumnSize = 8;
rgColumnDescs[0].dbcid.eKind = DBKIND_NAME; /* only DBKIND_NAME supported */
rgColumnDescs[0].dbcid.uName.pwszName = L"i";
rgColumnDescs[1].wType = DBTYPE_WSTR;
rgColumnDescs[1].ulColumnSize = 40;
rgColumnDescs[1].dbcid.eKind = DBKIND_NAME; /* only DBKIND_NAME supported */
rgColumnDescs[1].dbcid.uName.pwszName = L"name";
rgColumnDescs[2].wType = DBTYPE_R8;
rgColumnDescs[2].ulColumnSize = 8;
rgColumnDescs[2].dbcid.eKind = DBKIND_NAME; /* only DBKIND_NAME supported */
rgColumnDescs[2].dbcid.uName.pwszName = L"age";
hr = spTableDef->CreateTable(
NULL /* outer unknown */,
&in_table /*id of table to create */,
cColumnDescs /* number of columns */,
rgColumnDescs /* description of columns */,
IID_IUnknown /* interface to get on new data set */,
0 /* number of property sets */,
NULL /* property sets */,
NULL /* id of table created, always equal to the requested id */,
&spUnkNewTable.p /* pointer to new data set */ );
}
return hr;
}
HRESULT DeleteNewTable( CComPtr<IUnknown>& spUnkSession )
{
/* spUnkSession contains a pointer to the IUnknown interface of an open Session Object */
/* This method deletes a table named newtable from the sasuser library */
HRESULT hr = E_FAIL;
CComQIPtr<ITableDefinition> spTableDef = spUnkSession;
if( spTableDef == NULL )
cout << "ERROR: ITableDefinition not found" << endl;
else
{
DBID tableid;
tableid.eKind = DBKIND_NAME; /* only DBKIND_NAME supported */
tableid.uName.pwszName = L"sasuser.newtable";
hr = spTableDef->DropTable( &tableid );
}
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( CreateNewTable( spUnkSession ) ); /* create a data set named newtable in the sasuser library */
FAIL_IF( DeleteNewTable( spUnkSession ) ); /* delete a data set named newtable in the sasuser library */
}
catch( _com_error& e )
{
cout << "ERROR: 0x" << hex << setw(8) << setfill('0') << right << e.Error() << endl;
}
CoUninitialize();
return 0;
}