Using Dynamic Accessors

Dynamic accessors allow you to access a data source when you have no knowledge of the database schema (underlying structure). The OLE DB Templates library provides several classes to help you do this.

The DynamicConsumer sample shows how to use the dynamic accessor classes to obtain column information and dynamically create accessors.

Using CDynamicAccessor

CDynamicAccessor allows you to access a data source when you have no knowledge of the database schema (the database's underlying structure). CDynamicAccessor methods obtain column information such as column names, count, and data type. You use this column information to create an accessor dynamically at run time. The column information is stored in a buffer that is created and managed by this class. Obtain data from the buffer using the GetValue method.

Example

Code

// Using_Dynamic_Accessors.cpp
// compile with: /c /EHsc
#include <stdio.h>
#include <objbase.h>
#include <atldbcli.h>


int main( int argc, char* argv[] )
{
    HRESULT hr = CoInitialize( NULL );

    CDataSource ds;
    CSession ss;

    CTable<CDynamicAccessor> rs;

    // The following is an example initialization string:
    hr = ds.OpenFromInitializationString(L"Provider=SQLOLEDB.1;"
      L"Integrated Security=SSPI;Persist Security Info=False;"
      L"Initial Catalog=Loginname;Data Source=your_data_source;"
      L"Use Procedure for Prepare=1;Auto Translate=True;"
      L"Packet Size=4096;Workstation ID=LOGINNAME01;"
      L"Use Encryption for Data=False;"
      L"Tag with column collation when possible=False");

    hr = ss.Open( ds );
    hr = rs.Open( ss, "Shippers" );

    hr = rs.MoveFirst( );
    while( SUCCEEDED( hr ) && hr != DB_S_ENDOFROWSET )
    {
        for( size_t i = 1; i <= rs.GetColumnCount( ); i++ )
        {
            DBTYPE type;
            rs.GetColumnType( i, &type );
            printf_s( "Column %d [%S] is of type %d\n",
                      i, rs.GetColumnName( i ), type ); 
         
            switch( type )
            {
                case DBTYPE_WSTR:
                    printf_s( "value is %S\n",
                              (WCHAR*)rs.GetValue( i ) );
                break;
                case DBTYPE_STR:
                    printf_s( "value is %s\n",
                              (CHAR*)rs.GetValue( i ) );
                default:
                    printf_s( "value is %d\n",
                              *(long*)rs.GetValue( i ) );
            }
        }
        hr = rs.MoveNext( );
    }

    rs.Close();   
    ss.Close();
    ds.Close();
    CoUninitialize();

    return 0;
}

Using CDynamicStringAccessor

CDynamicStringAccessor works like CDynamicAccessor, except in one important way. While CDynamicAccessor requests data in the native format reported by the provider, CDynamicStringAccessor requests that the provider fetch all data accessed from the data store as string data. This is especially useful for simple tasks that do not require calculation of values in the data store, such as displaying or printing the data store's contents.

Use CDynamicStringAccessor methods to obtain column information. You use this column information to create an accessor dynamically at run time. The column information is stored in a buffer created and managed by this class. Obtain data from the buffer using CDynamicStringAccessor::GetString or store it to the buffer using CDynamicStringAccessor::SetString.

Example

Code

// Using_Dynamic_Accessors_b.cpp
// compile with: /c /EHsc
#include <stdio.h>
#include <objbase.h>
#include <atldbcli.h>

int main( int argc, char* argv[] )
{
    HRESULT hr = CoInitialize( NULL );
    if (hr != S_OK)
    {
        exit (-1);
    }

    CDataSource ds;
    CSession ss;

    CTable<CDynamicStringAccessor> rs;

    // The following is an example initialization string:
    hr = ds.OpenFromInitializationString(L"Provider=SQLOLEDB.1;"
      L"Integrated Security=SSPI;Persist Security Info=False;"
      L"Initial Catalog=Loginname;Data Source=your_data_source;"
      L"Use Procedure for Prepare=1;Auto Translate=True;"
      L"Packet Size=4096;Workstation ID=LOGINNAME01;"
      L"Use Encryption for Data=False;"
      L"Tag with column collation when possible=False");

    hr = ss.Open( ds );
    hr = rs.Open( ss, "Shippers" );

    hr = rs.MoveFirst( );
    while( SUCCEEDED( hr ) && hr != DB_S_ENDOFROWSET )
    {
        for( size_t i = 1; i <= rs.GetColumnCount( ); i++ )
        {
            printf_s( "column %d value is %s\n", 
                      i, rs.GetString( i ) );
        }
        hr = rs.MoveNext( );
    }

    rs.Close();   
    ss.Close();
    ds.Close();
    CoUninitialize();

   return 0;

}

Using CDynamicParameterAccessor

CDynamicParameterAccessor is similar to CDynamicAccessor, except that CDynamicParameterAccessor obtains parameter information to be set by calling the ICommandWithParameters interface. The provider must support ICommandWithParameters for the consumer to use this class.

The parameter information is stored in a buffer created and managed by this class. Obtain parameter data from the buffer by using CDynamicParameterAccessor::GetParam and CDynamicParameterAccessor::GetParamType.

For an example demonstrating how to use this class to execute a SQL Server stored procedure and get the output parameter values, see Knowledge Base article Q058860, "HOWTO: Execute Stored Procedure using CDynamicParameterAccessor." Knowledge Base articles are available in the MSDN Library Visual Studio documentation or at https://support.microsoft.com.

See Also

Tasks

DynamicConsumer Sample: Uses Dynamic Accessor and Schema Rowset Classes to Read Metadata from a Database

Concepts

Using Accessors

Reference

CDynamicAccessor Class

CDynamicStringAccessor Class

CDynamicParameterAccessor Class