Utilizar descriptores de acceso dinámicos

Los descriptores de acceso dinámicos permiten acceder a un origen de datos cuando no se conoce el esquema de la base de datos (estructura subyacente). La biblioteca de plantillas OLE DB proporciona varias clases que le ayudarán.

El ejemplo DynamicConsumer muestra cómo usar las clases de descriptor de acceso dinámico para obtener información de columna y crear descriptores de acceso dinámicamente.

Uso de CDynamicAccessor

CDynamicAccessor permite acceder a un origen de datos cuando se desconoce el esquema de la base de datos (estructura subyacente de la base de datos). Los métodos CDynamicAccessor obtienen información de columna, como nombres de columna, recuento y tipo de datos. Esta información de columna se usa para crear un descriptor de acceso dinámicamente en tiempo de ejecución. La información de columna se almacena en un búfer creado y administrado por esta clase. Para obtener datos del búfer, use el método GetValue.

Ejemplo: descriptores de acceso CDynamic

// 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;
}

Uso de CDynamicStringAccessor

CDynamicStringAccessor funciona como CDynamicAccessor, excepto en un aspecto importante. Aunque CDynamicAccessor solicita datos con el formato nativo notificado por el proveedor, CDynamicStringAccessor solicita que el proveedor capture todos los datos a los que se accede desde el almacén de datos como datos de cadena. Este proceso es especialmente útil para tareas sencillas que no requieren el cálculo de valores en el almacén de datos, como mostrar o imprimir el contenido del almacén de datos.

Use los métodos CDynamicStringAccessor para obtener información de columna. Esta información de columna se usa para crear un descriptor de acceso dinámicamente en tiempo de ejecución. La información de columna se almacena en un búfer creado y administrado por esta clase. Para obtener datos del búfer, use CDynamicStringAccessor::GetString. Para almacenarlos en el búfer, use CDynamicStringAccessor::SetString.

Ejemplo: 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;
}

Uso de CDynamicParameterAccessor

CDynamicParameterAccessor es similar a CDynamicAccessor, excepto en que CDynamicParameterAccessor obtiene información de parámetros que se debe establecer con una llamada a la interfaz ICommandWithParameters. El proveedor debe admitir ICommandWithParameters para que el consumidor pueda usar esta clase.

La información de parámetros se almacena en un búfer creado y administrado por esta clase. Para obtener datos de parámetros del búfer, use CDynamicParameterAccessor::GetParam y CDynamicParameterAccessor::GetParamType.

Para obtener un ejemplo que muestre cómo usar esta clase para ejecutar un procedimiento almacenado de SQL Server y obtener los valores de parámetro de salida, consulte el código de ejemplo DynamicConsumer en el repositorio VCSamples de Microsoft en GitHub.

Consulte también

Usar descriptores de acceso
CDynamicAccessor (Clase)
CDynamicStringAccessor (Clase)
CDynamicParameterAccessor (Clase)
Ejemplo DynamicConsumer