Sdílet prostřednictvím


Použití více přístupových objektů pro sadu řádků

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

  • Více sad řádků pro čtení a 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 také mít možnost zapisovat data do všech sloupců kromě primárního klíče (protože do sloupce primárního klíče nemůžete zapisovat). V tomto případě nastavíte dva přístupové objekty:

    • Příslušenství 0 obsahuje všechny sloupce.

    • Přistupovací objekt 1 obsahuje všechny sloupce kromě primárního klíče.

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

    Můžete nastavit samostatné přístupové objekty, ve kterých první přístupový objekt obsahuje všechny sloupce s výjimkou sloupců s velkými daty a načítá data z těchto sloupců automaticky; prvním příslušenstvím je automatický přístup. Druhý přístup načte pouze sloupec, který obsahuje velká data, ale nenačítá data z tohoto sloupce automaticky. Můžete mít další metody, které aktualizují nebo načítají velká data na vyžádání.

    • Příslušenství 0 je automatický příslušenství; načte všechny sloupce s výjimkou sloupců s velkými daty.

    • Příslušenství 1 není automatickým příslušenstvím; načte sloupec s velkými daty.

    Pomocí automatického argumentu určete, zda je příslušenstvím automatického přístupového objektu.

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

Obvykle vytváříte přístupové objekty pomocí BEGIN_ACCESSOR a END_ACCESSOR maker. Můžete také použít atribut db_accessor . (Přístupové objekty jsou podrobněji popsány v tématu Záznamy uživatelů.) Makra nebo atribut určují, jestli je příslušenství automatické nebo neautomatické přístupové objekty:

  • V automatickém přístupové objektu můžete automaticky přesouvat metody, jako MoveFirstje , MoveLastMoveNext, a MovePrev načítat data pro všechny zadané sloupce. Příslušenství 0 by mělo být automatickým příslušenstvím.

  • V neautomatické přístupové objektu se načítání neprojeví, dokud explicitně nezavoláte metodu, jako Updateje , Insert, Fetchnebo Delete. Ve scénářích popsaných výše možná nebudete chtít načíst všechny sloupce při každém přesunu. Jeden nebo více sloupců můžete umístit do samostatného přístupového objektu a nastavit ho jako neautomatické příslušenství, jak je znázorněno níže.

Následující příklad používá více přístupových objektů ke čtení a zápisu do tabulky úloh databáze pubs SQL Serveru pomocí více přístupových objektů. Tento příklad je nejběžnějším použitím více přístupových objektů; viz výše uvedený scénář více sad řádků pro čtení a zápis.

Třída záznamu uživatele je následující. Nastaví dva přístupové objekty: přistupovací objekt 0 obsahuje pouze sloupec primárního klíče (ID) a příslušenství 1 obsahuje další 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 následující. Volání MoveNext automaticky načte data z ID sloupce primárního klíče pomocí přístupového objektu 0. Všimněte si, jak Insert metoda blízko konce používá přístupové objekty 1, aby se zabránilo zápisu do sloupce primárního klíče.

int main(int argc, char* argv[])
{
    // Initialize 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é

Použití přístupových objektů
Uživatelské záznamy