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.

The DynamicConsumer sample shows how to use the dynamic accessor classes to get 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 get 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. Get data from the buffer using the GetValue method.

Example: CDynamic accessors

// 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. The process is especially useful for simple tasks that don't require calculation of values in the data store, such as displaying or printing the data store's contents.

Use CDynamicStringAccessor methods to get 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. Get data from the buffer using CDynamicStringAccessor::GetString or store it to the buffer using CDynamicStringAccessor::SetString.

Example: CDynamicStringAccessor

// 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 gets 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. Get 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 the DynamicConsumer sample code in the Microsoft VCSamples repository on GitHub.

See also

Using Accessors
CDynamicAccessor Class
CDynamicStringAccessor Class
CDynamicParameterAccessor Class
DynamicConsumer Sample