Использование динамических методов доступа

Динамические методы доступа позволяют получить доступ к источнику данных, если у вас нет знаний о схеме базы данных (базовой структуре). Библиотека шаблонов OLE DB предоставляет несколько классов, которые помогут вам.

В примере DynamicConsumer показано, как использовать классы динамического доступа для получения сведений о столбцах и динамического создания методов доступа.

Использование CDynamicAccessor

CDynamicAccessor позволяет получить доступ к источнику данных, если у вас нет знаний о схеме базы данных (базовой структуре базы данных). CDynamicAccessor методы получают сведения о столбцах, такие как имена столбцов, количество и тип данных. Эти сведения столбца используются для динамического создания метода доступа во время выполнения. Сведения о столбце хранятся в буфере, который создается и управляется этим классом. Получение данных из буфера с помощью метода GetValue .

Пример: методы доступа 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;
}

Использование CDynamicStringAccessor

CDynamicStringAccessor работает как CDynamicAccessor, за исключением одного важного способа. Хотя CDynamicAccessor запрашивает данные в собственном формате, сообщаемом поставщиком, CDynamicStringAccessor запрашивает получение всех данных из хранилища данных в виде строковых данных. Этот процесс особенно полезен для простых задач, которые не требуют вычисления значений в хранилище данных, таких как отображение или печать содержимого хранилища данных.

Используйте CDynamicStringAccessor методы для получения сведений о столбцах. Эти сведения столбца используются для динамического создания метода доступа во время выполнения. Сведения о столбце хранятся в буфере, созданном и управляемом этим классом. Получите данные из буфера с помощью CDynamicStringAccessor::GetString или сохраните его в буфер с помощью CDynamicStringAccessor::SetString.

Пример: 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;
}

Использование CDynamicParameterAccessor

CDynamicParameterAccessor аналогичен CDynamicAccessor, за исключением того, что CDynamicParameterAccessor получает сведения о параметрах, которые необходимо задать путем вызова интерфейса ICommandWithParameters. Для использования этого класса поставщик должен поддерживать интерфейс ICommandWithParameters для потребителя.

Сведения о параметрах хранятся в буфере, создаваемом и управляемом данным классом. Получение данных параметров из буфера с помощью CDynamicParameterAccessor::GetParam и CDynamicParameterAccessor::GetParamType.

Пример использования этого класса для выполнения хранимой процедуры SQL Server и получения значений выходных параметров см . в примере кода DynamicConsumer в репозитории Microsoft VCSamples на сайте GitHub.

См. также

Использование методов доступа
Класс CDynamicAccessor
Класс CDynamicStringAccessor
Класс CDynamicParameterAccessor
Пример DynamicConsumer