Udostępnij za pośrednictwem


Używanie wielu metod dostępu w zestawie wierszy

Istnieją trzy podstawowe scenariusze, w których należy użyć wielu metod dostępu:

  • Wiele zestawów wierszy odczytu/zapisu. W tym scenariuszu masz tabelę z kluczem podstawowym. Chcesz mieć możliwość odczytania wszystkich kolumn w wierszu, w tym klucza podstawowego. Chcesz również zapisywać dane we wszystkich kolumnach z wyjątkiem klucza podstawowego (ponieważ nie można zapisać w kolumnie klucza podstawowego). W takim przypadku skonfigurujesz dwa metody dostępu:

    • Akcesorium 0 zawiera wszystkie kolumny.

    • Akcesorium 1 zawiera wszystkie kolumny z wyjątkiem klucza podstawowego.

  • Wydajność. W tym scenariuszu co najmniej jedna kolumna zawiera dużą ilość danych, na przykład grafiki, dźwięku lub plików wideo. Za każdym razem, gdy przejdziesz do wiersza, prawdopodobnie nie chcesz pobierać kolumny z dużym plikiem danych, ponieważ spowoduje to spowolnienie wydajności aplikacji.

    Można skonfigurować oddzielne metody dostępu, w których pierwsza metoda dostępu zawiera wszystkie kolumny, z wyjątkiem tych z dużymi danymi, i pobiera dane z tych kolumn automatycznie; pierwszym akcesorem jest automatyczne akcesorium. Druga metoda dostępu pobiera tylko kolumnę przechowującą duże dane, ale nie pobiera danych z tej kolumny automatycznie. Możesz mieć inne metody aktualizowania lub pobierania dużych danych na żądanie.

    • Akcesorium 0 jest automatycznym akcesorem; pobiera wszystkie kolumny z wyjątkiem tych z dużymi danymi.

    • Akcesorium 1 nie jest automatycznym akcesorem; pobiera kolumnę z dużymi danymi.

    Użyj argumentu automatycznego, aby określić, czy akcesorium jest akcesorem automatycznym.

  • Wiele kolumn ISequentialStream. W tym scenariuszu masz więcej niż jedną kolumnę przechowującą ISequentialStream dane. Jednak każde akcesorium jest ograniczone do jednego ISequentialStream strumienia danych. Aby rozwiązać ten problem, skonfiguruj kilka metod dostępu, z których każdy ma jeden ISequentialStream wskaźnik.

Zwykle można tworzyć metody dostępu przy użyciu makr BEGIN_ACCESSOR i END_ACCESSOR . Można również użyć atrybutu db_accessor . (Metody dostępu zostały opisane w dalszej części Rekordy użytkowników). Makra lub atrybut określają, czy akcesorium jest automatycznym, czy nieautomatycznym akcesorem:

  • W przypadku automatycznego dostępu metody przenoszenia, takie jak MoveFirst, MoveLast, MoveNexti MovePrev pobierają dane dla wszystkich określonych kolumn automatycznie. Akcesorium 0 powinno być automatycznym akcesorem.

  • W metodzie dostępu nieautomatyczne pobieranie nie występuje, dopóki jawnie nie wywołasz metody, takiej jak Update, Insert, Fetchlub Delete. W opisanych powyżej scenariuszach możesz nie chcieć pobrać wszystkich kolumn w każdym przeniesieniu. Można umieścić co najmniej jedną kolumnę w osobnym metodzie dostępu i zrobić to nieautomatyczne akcesorium, jak pokazano poniżej.

W poniższym przykładzie użyto wielu metod dostępu do odczytu i zapisu w tabeli zadań bazy danych pubs programu SQL Server przy użyciu wielu metod dostępu. Ten przykład jest najczęstszym zastosowaniem wielu metod dostępu; zobacz powyższy scenariusz "wiele zestawów wierszy do odczytu/zapisu".

Klasa rekordów użytkownika jest następująca. Konfiguruje dwa metody dostępu: akcesorium 0 zawiera tylko kolumnę klucza podstawowego (ID) i metodę dostępu 1 zawiera inne kolumny.

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

Główny kod jest następujący. Wywołanie MoveNext automatycznie pobiera dane z identyfikatora kolumny klucza podstawowego przy użyciu metody dostępu 0. Zwróć uwagę, Insert że metoda w pobliżu końca używa metody dostępu 1, aby uniknąć zapisywania w kolumnie klucza podstawowego.

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

Zobacz też

Korzystanie z metod dostępu
Rekordy użytkowników