Contents SAS IOM Data Provider Previous Next

Command Processing

To process SQL statements, the SAS IOM data provider implements OLE DB command objects.  Each command object encapsulates a connection to a particular database management system (DBMS) and one SQL statement. Clients can repeatedly use the same command object for different commands and queries by resetting the SQL statement.  However, the command object's DBMS connection cannot be changed.  If an application needs to connect to another DBMS, a new command object must be created.   The DBMS is automatically disconnected when the command object is destroyed.   

In addition to exposing the mandatory interfaces on the command object, the IOM provider also exposes  ICommandPrepare and ISupportErrorInfo. 

Setting Session Properties for Command Objects

Command objects are spawned from OLE DB session objects.  To access any of the data sets from an established data source connection using command objects, a session object first needs to be created by calling IDBCreateSession::CreateSession().   Properties set on the session object determine which SQL engine will be used to create command objects.  The client can set the following properties on the session object before creating a command object: 

These properties belong to the DBPROPSET_SAS_SESSION property set.  If the client does not set these properties, the default property values will be used when the command object is created.  Whatever properties are set on the session object pertain to all command objects that are created unless the session properties are reset. 

The following example starts with an initialized data source component,  pDSO,  creates a session object and sets the two session properties that are relevant to command objects:

        LPUNKNOWN                                       pDSO = NULL;
        LPUNKNOWN                                       pSession = NULL;
        IDBCreateSession *                              pIDBCreateSession = NULL;
        ISessionProperties *                            pISessionProperties = NULL;
        DBPROPSET                                       PropSet;
        DBPROP                                          prop[2];

            pDSO->QueryInterface( IID_IDBCreateSession, (void **) &pIDBCreateSession );     

            //-- Create a session object

            pIDBCreateSession->CreateSession( NULL, IID_ISessionProperties, (LPUNKNOWN *) &pISessionProperties);
        
        //set engine name; no connection string
                                                                                                                                                
        prop[0].dwPropertyID            = DBPROP_SAS_SQLENGINE;                                                                                 
        prop[0].dwOptions               = DBPROPOPTIONS_REQUIRED;                                               
        prop[0].colid                   = DB_NULLID;                                                                    
        V_VT(&(prop[0].vValue))         = VT_BSTR;                                                                      
        V_BSTR(&(prop[0].vValue))       = SysAllocString(L"oracle");
        prop[1].dwPropertyID            = DBPROP_SAS_SQLCONNECTIONSTRING;                                                                                       
        prop[1].dwOptions               = DBPROPOPTIONS_REQUIRED;                                               
        prop[1].colid                   = DB_NULLID;                                                                    
        V_VT(&(prop[1].vValue))         = VT_BSTR;                                                                      
        V_BSTR(&(prop[1].vValue))       = SysAllocString(L"user=bob password=tiger path=briggs_1234");

        PropSet.rgProperties= ∝
        PropSet.cProperties=2;  
        PropSet.guidPropertySet = DBPROPSET_SAS_SESSION;

        pISessionProperties->SetProperties(1, &PropSet);
        
        

Creating the Command Object

After properties are set, all command objects are created using the engine and connection string that are previously specified.  The client may reset these session properties by repeating the above lines with a different engine and connection string.  The IDBCreateCommand interface is needed to create the command object. The following lines of code return the IDBCreateCommand interface and use it to instantiate a command object:

        IDBCreateCommand *                      pIDBCreateCommand = NULL;
        ICommandText *                          pICommandText;
        pISessionProperties->QueryInterface( IID_IDBCreateCommand, (void **)
&pIDBCreateCommand);        pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText,
(LPUNKNOWN *) &pICommandText);

Setting the Command Text

Each command object may hold one SQL statement, which is referred to as its command text. The command text is set with the  ICommandText::SetCommandText() method.  The command text syntax is DBMS dependent. Clients should pass in DBGUID_DEFAULT as the dialect.

        ICommandText *          pICommandText;
        hr = pICommandText->SetCommandText(DBGUID_DEFAULT, L"select * from patients where age > 66");

Executing the Command

After the command text and command properties have been set, execute the command by invoking ICommand::Execute() .  If the command text is a statement that returns rows, pass in a requested rowset interface and a rowset will be returned by this method.  If the command text does not return rows (such as an SQL command) then pass in IID_NULL for the requested interface or NULL for ppRowset.  Two arguments to this method,  pParams and cRowsAffected, are currently ignored by the IOM provider so that the client can set them to NULL.



        memset( (void *) &Params, 0, sizeof( DBPARAMS ) );

        hr = pICommandText->QueryInterface( IID_ICommand, (void **) &pICommand );

        hr = pICommand->Execute(
                                                NULL,           // no aggregation
                                                IID_IRowset,    // requested interface for the returned rowset
                                                NULL,           // pParams - CURRENTLY IGNORED
                                                NULL,           // cRowsAffected - CURRENTLY IGNORED
                                                &pQueryRowset);   // IUnknown **  ppRowset);


    hr = pICommandPrepare->Unprepare();         

The OLE DB specification requires that you close the rowset before you prepare and execute again.

 

Attributes of the Returned Rowset

If the client requested an interface for a returned rowset on the ICommand::Execute method, the returned rowset will be a read-only rowset with the the properties DBPROP_IRowsetUpdate and DBPROP_IRowsetChange both set to VARIANT_FALSE.

Contents SAS IOM Data Provider Previous Next