Compartilhar via


Usando vários acessadores em um conjunto de linhas.

Há três cenários básicos, nos quais você precisa usar acessadores vários:

  • Vários conjuntos de linhas de leitura/gravação. Nesse cenário, você deve ter uma tabela com uma chave primária. Você deseja ser capaz de ler todas as colunas na linha, incluindo a chave primária. Você também deseja ser capaz de gravar dados para todas as colunas, exceto a chave primária (porque você não pode gravar a coluna chave primária). Nesse caso, você definir dois acessadores:

    • O acessador 0 contém todas as colunas.

    • O acessador 1 contém todas as colunas, exceto a chave primária.

  • Desempenho. Nesse cenário, uma ou mais colunas contêm uma grande quantidade de dados, por exemplo, elementos gráficos, som ou vídeo arquivos. Sempre que você mover uma linha, você provavelmente não deseja recuperar a coluna com o arquivo de dados grandes, porque fazer então reduzia o desempenho do aplicativo.

    Você pode configurar acessadores separados na qual o acessador primeiro contém todas as colunas, exceto aquele com dados grandes e ele recupera dados dessas colunas automaticamente; Este é o acessador de auto. O acessador segundo recupera somente a coluna que contém dados grandes, mas ele não recuperar dados de nesta coluna automaticamente. Você pode ter outros métodos para atualizar ou buscar os dados de grandes demanda.

    • O acessador 0 é um acessador automático; ele recupera todas as colunas, exceto aquele com dados grandes.

    • O acessador 1 não é um acessador automático; ele recupera a coluna de dados grandes.

    Use o argumento de auto para especificar se o acessador é um acessador de auto.

  • Várias colunas de ISequentialStream. Nesse cenário, você tem que de contém mais de uma coluna ISequentialStream de dados. No entanto, cada acessador é limitada a uma ISequentialStream fluxo de dados. Para resolver esse problema, configure vários acessadores, cada uma contendo um ISequentialStream ponteiro.

Você normalmente cria acessadores usando o BEGIN_ACCESSOR e END_ACCESSOR macros. Você também pode usar o db_accessor atributo. (Acessadores estão descritos em mais detalhes em Registros de usuário.) As macros ou o atributo especificar se um acessador automático ou um acessador não é automático:

  • Um acessador automático, mover métodos como MoveFirst, MoveLast, MoveNext, e MovePrev recuperar os dados para todas as colunas de especificado automaticamente. O acessador 0 deve ser o acessador automático.

  • Um acessador não é automático, a recuperação não ocorre até que você chamar explicitamente um método como atualização, Inserir, busca, ou Excluir. Nas situações descritas acima, você talvez não queira recuperar todas as colunas em cada movimento. Você pode colocar uma ou mais colunas em um acessador separado e verifique um acessador não é automático, como mostrado abaixo.

O exemplo a seguir usa vários acessadores para leitura e gravação para a tabela de trabalhos do banco de dados de pubs SQL Server usando vários acessadores. Este é o uso mais comum de vários acessadores; Consulte os "conjuntos múltiplos de leitura/gravação" cenário acima.

A classe de registro de usuário é o seguinte. Define dois acessadores: o acessador 0 contém somente a coluna chave primária (ID) e assessor 1 outras colunas.

class CJobs
{
public:
    enum {
        sizeOfDescription = 51
    };

    short nID;
    char szDescription[ sizeOfDescription ];
    short nMinLvl;
    short nMaxLvl;

    DWORD dwID;
    DWORD dwDescription;
    DWORD dwMinLvl;
    DWORD dwMaxLvl;

BEGIN_ACCESSOR_MAP(CJobs, 2)
    // Accessor 0 is the automatic accessor
    BEGIN_ACCESSOR(0, true)
        COLUMN_ENTRY_STATUS(1, nID, dwID)
    END_ACCESSOR()
    // Accessor 1 is the non-automatic accessor
    BEGIN_ACCESSOR(1, true)
        COLUMN_ENTRY_STATUS(2, szDescription, dwDescription)
        COLUMN_ENTRY_STATUS(3, nMinLvl, dwMinLvl)
        COLUMN_ENTRY_STATUS(4, nMaxLvl, dwMaxLvl)
    END_ACCESSOR()
END_ACCESSOR_MAP()
};

O código principal é o seguinte. Chamando MoveNext recupera automaticamente os dados da ID da coluna de chave primária usando 0 do acessador. Observe como o Inserir método perto o acessador de usos finais 1 para evitar a escrita para a coluna de chave primária.

int main(int argc, char* argv[])
{
    // Initalize COM
    ::CoInitialize(NULL);

    // Create instances of the data source and session
    CDataSource source;
    CSession session;
    HRESULT hr = S_OK;

    // Set initialization properties
    CDBPropSet dbinit(DBPROPSET_DBINIT);
    dbinit.AddProperty(DBPROP_AUTH_USERID, OLESTR("my_user_id"));
    dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("pubs"));
    dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("(local)"));

    hr = source.Open("SQLOLEDB.1", &dbinit);
    if (hr == S_OK)
    {
        hr = session.Open(source);
        if (hr == S_OK)
        {
            // Ready to fetch/access data
            CTable<CAccessor<CJobs> > jobs;

            // Set properties for making the rowset a read/write cursor
            CDBPropSet dbRowset(DBPROPSET_ROWSET);
            dbRowset.AddProperty(DBPROP_CANFETCHBACKWARDS, true);
            dbRowset.AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
            dbRowset.AddProperty(DBPROP_IRowsetChange, true);
            dbRowset.AddProperty(DBPROP_UPDATABILITY,
                DBPROPVAL_UP_INSERT | DBPROPVAL_UP_CHANGE |
                DBPROPVAL_UP_DELETE);
   
            hr = jobs.Open(session, "jobs", &dbRowset);
            if (hr == S_OK)
            {
                // Calling MoveNext automatically retrieves ID
                // (using accessor 0)
                while(jobs.MoveNext() == S_OK)
                   printf_s("Description = %s\n", jobs.szDescription);

                hr = jobs.MoveFirst();
                if (hr == S_OK)
                {
                    jobs.nID = 25;
                    strcpy_s(&jobs.szDescription[0],
                             jobs.sizeOfDescription,
                             "Developer");
                    jobs.nMinLvl = 10;
                    jobs.nMaxLvl = 20;

                    jobs.dwDescription = DBSTATUS_S_OK;
                    jobs.dwID = DBSTATUS_S_OK;
                    jobs.dwMaxLvl = DBSTATUS_S_OK;
                    jobs.dwMinLvl = DBSTATUS_S_OK;

                    // Insert method uses accessor 1
                    // (to avoid writing to the primary key column)
                    hr = jobs.Insert(1);   
                }
                jobs.Close();
            }
            session.Close();
        }
        source.Close();
    }

    // Uninitialize COM
    ::CoUninitialize();
    return 0;
}

Consulte também

Conceitos

Usar acessadores

Registros de usuário