Sdílet prostřednictvím


Použití několika přístupových objektů na sadě řádků

Existují tři základní scénáře, ve kterých potřebujete použít více přistupujících objektů:

  • Více sad řádků pro čtení/zápis. V tomto scénáři máte tabulku s primárním klíčem. Chcete mít možnost číst všechny sloupce v řádku, včetně primárního klíče. Chcete mít také možnost zapsat data do všech sloupců s výjimkou primárního klíče (protože nelze zapisovat do sloupce primárního klíče). V tomto případě nastavíte dva přistupující objekty:

    • Přistupující objekt 0 obsahuje všechny sloupce.

    • Přistupující objekt 1 obsahuje všechny sloupce s výjimkou primárního klíče.

  • Výkon. V tomto scénáři obsahuje jeden nebo více sloupců velké množství dat, například grafiku, zvuk nebo soubory videa. Pokaždé, když se přesunete na řádek, pravděpodobně nechcete načíst sloupec s velkým datovým souborem, protože to by zpomalilo výkon vaší aplikace.

    Můžete nastavit samostatné přistupující objekty, ve kterých první přistupující objekt obsahuje všechny sloupce s výjimkou toho s velkými daty a načítá data z těchto sloupců automaticky; toto je automatický přistupující objekt. Druhý přistupující objekt načítá pouze sloupec, obsahující velká data, ale nenačítá dat z tohoto sloupce automaticky. Můžete mít jiné metody pro aktualizování nebo načítání velkých dat na požádání.

    • Přistupující objekt 0 je automatický přistupující objekt; načte všechny sloupce kromě toho s velkými daty.

    • Přistupující objekt 1 není automatický přistupující objekt; načítá sloupec s velkými daty.

    Použijte argument auto pro určení, zda je přistupující objekt automatický přistupující objekt.

  • Více sloupců ISequentialStream. V tomto scénáři máte více než jeden sloupec obsahující ISequentialStream data. Každý přistupující objekt je však omezen na jeden datový proud ISequentialStream. Chcete-li tento problém vyřešit, nastavte několik přistupujících objektů, každý obsahující jeden ukazatel ISequentialStream.

Obvykle vytvoříte přistupující objekty pomocí maker BEGIN_ACCESSOR a END_ACCESSOR. Můžete také použít atribut db_accessor. (Přistupující objekty jsou popsány dále v Záznamech uživatele.) Makra nebo atribut určují, zda je přistupující objekt automatický nebo neautomatický přistupující objekt:

  • V automatickém přistupujícím objektu metody přesunu MoveFirst, MoveLast, MoveNext a MovePrev načítají data pro všechny zadané sloupce automaticky. Přistupující objekt 0 by měla být automatický přistupující objekt.

  • V neautomatickém přistupujícím objektu k načtení nedojde, dokud explicitně nezavoláte metodu, jako je Update, Insert, Fetch nebo Delete. V případech popsaných výše není vhodné načítat všechny sloupce při každém přesunu. Můžete umístit jeden nebo více sloupců do samostatného přistupujícího objektu a udělat jej neautomatickým přistupujícím objektem, jak je ukázáno níže.

Následující příklad používá více přistupujících objektů pro čtení a zápis do tabulky jobs databáze pubs serveru SQL Server pomocí více přistupujících objektů. Toto je nejběžnější použití více přistupujících objektů; viz výše scénář "více sad řádků pro čtení/zápis".

Třída záznamu uživatele je jako následující. Nastavuje dva přistupující objekty: přistupující objekt 0 obsahuje pouze sloupec primárního klíče (ID) a přistupující objekt 1 obsahuje jiné sloupce.

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()
};

Hlavní kód je jako následující. Volání MoveNext automaticky načítá data ze sloupce primárního klíče ID pomocí přistupujícího objektu 0. Všimněte si, jak metoda Insert poblíž konce používá přistupující objekt 1 pro zamezení zapsání do sloupce primárního klíče.

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

Viz také

Koncepty

Použití přístupových objektů

Uživatelské záznamy