Udostępnij za pośrednictwem


TN054: wywoływanie obiektów DAO bezpośrednio podczas używania klas MFC DAO

Uwaga

DaO jest używany z bazami danych programu Access i jest obsługiwany za pośrednictwem pakietu Office 2013. DaO 3.6 jest wersją ostateczną i jest uważany za przestarzałą. Środowisko i kreatory języka Visual C++ nie obsługują dao (chociaż klasy DAO są uwzględnione i nadal można ich używać). Firma Microsoft zaleca używanie szablonów OLE DB lub ODBC i MFC dla nowych projektów. W przypadku obsługi istniejących aplikacji należy używać tylko dao.

W przypadku korzystania z klas baz danych MFC DAO mogą wystąpić sytuacje, w których konieczne jest bezpośrednie użycie dao. Zwykle tak nie będzie, ale MFC dostarczył kilka mechanizmów pomocnika ułatwiających wykonywanie bezpośrednich wywołań DAO prostych podczas łączenia klas MFC z bezpośrednimi wywołaniami DAO. Wykonywanie bezpośrednich wywołań DAO do metod obiektu DAO zarządzanego przez MFC powinno wymagać tylko kilku wierszy kodu. Jeśli musisz utworzyć i użyć obiektów DAO, które niezarządzane przez MFC, musisz wykonać nieco więcej pracy, wywołując Release obiekt. Ta uwaga techniczna wyjaśnia, kiedy możesz bezpośrednio wywołać dao, co mogą zrobić pomocnicy MFC, aby ci pomóc i jak korzystać z interfejsów OLE DAO. Na koniec ta uwaga zawiera kilka przykładowych funkcji pokazujących sposób wywoływania dao bezpośrednio dla funkcji zabezpieczeń DAO.

Kiedy wykonywać bezpośrednie wywołania DAO

Najbardziej typowe sytuacje związane z wykonywaniem bezpośrednich wywołań DAO występuje, gdy kolekcje muszą być odświeżane lub gdy implementujesz funkcje, które nie są opakowane przez MFC. Najważniejszą funkcją, która nie jest uwidoczniona przez MFC, jest bezpieczeństwo. Jeśli chcesz zaimplementować funkcje zabezpieczeń, musisz bezpośrednio użyć obiektów użytkowników DAO i grup. Oprócz zabezpieczeń istnieje tylko kilka innych funkcji DAO, które nie są obsługiwane przez MFC. Obejmują one klonowanie zestawu rekordów i funkcje replikacji bazy danych, a także kilka późnych dodatków do daO.

Krótkie omówienie implementacji dao i MFC

Zawijanie daO MFC ułatwia korzystanie z DAO dzięki obsłudze wielu szczegółów, dzięki czemu nie musisz martwić się o małe rzeczy. Obejmuje to inicjowanie OLE, tworzenie obiektów DAO i zarządzanie nimi (zwłaszcza obiektów kolekcji), sprawdzanie błędów i dostarczanie silnie typizowanego, prostszego interfejsu (bez wariantu lub BSTR argumentów). Możesz wykonywać bezpośrednie wywołania DAO i nadal korzystać z tych funkcji. Cały kod musi być wywoływany Release dla wszystkich obiektów utworzonych przez bezpośrednie wywołania DAO i nie modyfikuje żadnych wskaźników interfejsu, na których MFC może polegać wewnętrznie. Na przykład nie należy modyfikować elementu członkowskiego m_pDAORecordset otwartego CDaoRecordset obiektu, chyba że rozumiesz wszystkie wewnętrzne konsekwencje. Można jednak użyć interfejsu m_pDAORecordset , aby wywołać obiekt DAO bezpośrednio w celu pobrania kolekcji Pola. W takim przypadku element członkowski m_pDAORecordset nie zostanie zmodyfikowany. Po zakończeniu pracy z obiektem kolekcji Fields wystarczy wywołać Release obiekt .

Opis pomocników ułatwiających wywoływanie dao

Pomocnicy, którzy ułatwią wywoływanie obiektu DAO, są tymi samymi pomocnikami, które są używane wewnętrznie w klasach bazy danych MFC DAO. Te pomocniki służą do sprawdzania kodów powrotnych podczas wykonywania bezpośredniego wywołania DAO, rejestrowania danych wyjściowych debugowania, sprawdzania oczekiwanych błędów i zgłaszania odpowiednich wyjątków w razie potrzeby. Istnieją dwie podstawowe funkcje pomocnika i cztery makra mapowane na jeden z tych dwóch pomocników. Najlepszym wyjaśnieniem byłoby po prostu odczytanie kodu. Zobacz DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM i DAO_TRACE w usłudze AFXDAO. H, aby wyświetlić makra i zobacz AfxDaoCheck i AfxDaoTrace w języku DAOCORE. CPP.

Korzystanie z interfejsów OLE DAO

Interfejsy OLE dla każdego obiektu w hierarchii obiektów DAO są zdefiniowane w pliku nagłówkowym DBDAOINT. H, który znajduje się w katalogu \Program Files\Microsoft Visual Studio .NET 2003\VC7\include. Te interfejsy zapewniają metody, które umożliwiają manipulowanie całą hierarchią DAO.

W przypadku wielu metod w interfejsach DAO należy manipulować obiektem BSTR (ciągiem z prefiksem długości używanym w automatyzacji OLE). Obiekt BSTR zazwyczaj jest hermetyzowany w obrębie typu danych VARIANT . Sama klasa COleVariant MFC dziedziczy z typu danych VARIANT . W zależności od tego, czy kompilujesz projekt dla anSI, czy Unicode, interfejsy DAO będą zwracać anSI lub Unicode BSTR. Dwa makra, V_BSTR i V_BSTRT, są przydatne w celu zapewnienia, że interfejs DAO pobiera BSTR oczekiwany typ.

V_BSTR wyodrębni element członkowski bstrVal elementu COleVariant. To makro jest zwykle używane, gdy trzeba przekazać zawartość COleVariant elementu do metody interfejsu DAO. Poniższy fragment kodu przedstawia deklaracje i rzeczywiste użycie dwóch metod interfejsu DAOUser DAOUser, które korzystają z makra V_BSTR:

COleVariant varOldName;
COleVariant varNewName(_T("NewUser"), VT_BSTRT);

// Code to assign pUser to a valid value omitted DAOUser *pUser = NULL;

// These method declarations were taken from DBDAOINT.H
// STDMETHOD(get_Name) (THIS_ BSTR FAR* pbstr) PURE;
// STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE;
DAO_CHECK(pUser->get_Name(&V_BSTR (&varOldName)));
DAO_CHECK(pUser->put_Name(V_BSTR (&varNewName)));

Należy pamiętać, że VT_BSTRT argument określony w powyższym konstruktorze COleVariant gwarantuje, że w przypadku utworzenia wersji ANSI aplikacji i unicode dla wersji Unicode BSTR aplikacji będzie istnieć ANSI BSTRCOleVariant. To jest to, czego oczekuje DAO.

Drugie makro, V_BSTRT, wyodrębni element członkowski COleVariant ANSI lub Unicode bstrVal w zależności od typu kompilacji (ANSI lub Unicode). Poniższy kod pokazuje, jak wyodrębnić BSTR wartość z elementu COleVariant do elementu CString:

COleVariant varName(_T("MyName"), VT_BSTRT);
CString str = V_BSTRT(&varName);

Makro V_BSTRT wraz z innymi technikami otwierania innych typów przechowywanych w COleVariantprogramie jest pokazane w przykładzie DAOVIEW. W szczególności to tłumaczenie jest wykonywane w metodzie CCrack::strVARIANT . Ta metoda, jeśli to możliwe, tłumaczy wartość klasy COleVariant na wystąpienie CStringklasy .

Prosty przykład wywołania bezpośredniego do DAO

Mogą wystąpić sytuacje, w których konieczne jest odświeżenie bazowych obiektów kolekcji DAO. Zwykle nie powinno to być konieczne, ale jest to prosta procedura, jeśli jest to konieczne. Przykładem, kiedy może być konieczne odświeżenie kolekcji, jest działanie w środowisku wieloużytkownika z wieloma użytkownikami tworzącymi nowe definicje tabel. W takim przypadku kolekcja tabledefs może stać się nieaktualna. Aby odświeżyć kolekcję, wystarczy wywołać metodę Refresh określonego obiektu kolekcji i sprawdzić, czy występują błędy:

DAO_CHECK(pMyDaoDatabase->m_pDAOTableDefs->Refresh());

Należy pamiętać, że obecnie wszystkie interfejsy obiektów kolekcji DAO są nieudokumentowanymi szczegółami implementacji klas baz danych MFC DAO.

Używanie języka DAO bezpośrednio dla funkcji zabezpieczeń DAO

Klasy baz danych MFC DAO nie opakowują funkcji zabezpieczeń DAO. Aby używać niektórych funkcji zabezpieczeń DAO, należy wywołać metody interfejsów DAO. Poniższa funkcja ustawia systemową bazę danych, a następnie zmienia hasło użytkownika. Ta funkcja wywołuje trzy inne funkcje, które są następnie zdefiniowane.

void ChangeUserPassword()
{
    // Specify path to the Microsoft Access *// system database
    CString strSystemDB =
        _T("c:\\Program Files\\MSOffice\\access\\System.mdw");

    // Set system database before MFC initilizes DAO
    // NOTE: An MFC module uses only one instance
    // of a DAO database engine object. If you have
    // called a DAO object in your application prior
    // to calling the function below, you must call
    // AfxDaoTerm to destroy the existing database
    // engine object. Otherwise, the database engine
    // object already in use will be reused, and setting
    // a system datbase will have no effect.
    //
    // If you have used a DAO object prior to calling
    // this function it is important that DAO be
    // terminated with AfxDaoTerm since an MFC
    // module only gets one copy of the database engine
    // and that engine will be reused if it hasn't been
    // terminated. In other words, if you do not call
    // AfxDaoTerm and there is currently a database
    // initialized, setting the system database will
    // have no effect.
    SetSystemDB(strSystemDB);

    // User name and password manually added
    // by using Microsoft Access
    CString strUserName = _T("NewUser");
    CString strOldPassword = _T("Password");
    CString strNewPassword = _T("NewPassword");

    // Set default user so that MFC will be able
    // to log in by default using the user name and
    // password from the system database
    SetDefaultUser(strUserName, strOldPassword);

    // Change the password. You should be able to
    // call this function from anywhere in your
    // MFC application
    ChangePassword(strUserName, strOldPassword, strNewPassword);

    // ...
}

W następnych czterech przykładach pokazano, jak:

  • Ustaw systemowa baza danych DAO (. Plik MDW).

  • Ustaw domyślnego użytkownika i hasło.

  • Zmień hasło użytkownika.

  • Zmień hasło elementu . Plik MDB.

Ustawianie systemowej bazy danych

Poniżej przedstawiono przykładową funkcję ustawiającą systemową bazę danych, która będzie używana przez aplikację. Ta funkcja musi być wywoływana przed wykonaniem innych wywołań DAO.

// Set the system database that the
// DAO database engine will use

void SetSystemDB(CString& strSystemMDB)
{
    COleVariant varSystemDB(strSystemMDB, VT_BSTRT);

    // Initialize DAO for MFC
    AfxDaoInit();
    DAODBEngine* pDBEngine = AfxDaoGetEngine();

    ASSERT(pDBEngine != NULL);

    // Call put_SystemDB method to set the *// system database for DAO engine
    DAO_CHECK(pDBEngine->put_SystemDB(varSystemDB.bstrVal));
}

Ustawianie domyślnego użytkownika i hasła

Aby ustawić domyślnego użytkownika i hasło dla systemowej bazy danych, użyj następującej funkcji:

void SetDefaultUser(CString& strUserName,
    CString& strPassword)
{
    COleVariant varUserName(strUserName, VT_BSTRT);
    COleVariant varPassword(strPassword, VT_BSTRT);

    DAODBEngine* pDBEngine = AfxDaoGetEngine();
    ASSERT(pDBEngine != NULL);

    // Set default user:
    DAO_CHECK(pDBEngine->put_DefaultUser(varUserName.bstrVal));

    // Set default password:
    DAO_CHECK(pDBEngine->put_DefaultPassword(varPassword.bstrVal));
}

Zmienianie hasła użytkownika

Aby zmienić hasło użytkownika, użyj następującej funkcji:

void ChangePassword(CString &strUserName,
    CString &strOldPassword,
    CString &strNewPassword)
{
    // Create (open) a workspace
    CDaoWorkspace wsp;
    CString strWspName = _T("Temp Workspace");

    wsp.Create(strWspName, strUserName, strOldPassword);
    wsp.Append();

    // Determine how many objects there are *// in the Users collection
    short nUserCount;
    short nCurrentUser;
    DAOUser *pUser = NULL;
    DAOUsers *pUsers = NULL;

    // Side-effect is implicit OLE AddRef()
    // on DAOUser object:
    DAO_CHECK(wsp.m_pDAOWorkspace->get_Users(&pUsers));

    // Side-effect is implicit OLE AddRef()
    // on DAOUsers object
    DAO_CHECK(pUsers->getcount(&nUserCount));

    // Traverse through the list of users
    // and change password for the userid
    // used to create/open the workspace
    for(nCurrentUser = 0; nCurrentUser <nUserCount; nCurrentUser++)
    {
        COleVariant varIndex(nCurrentUser, VT_I2);
        COleVariant varName;

        // Retrieve information for user nCurrentUser
        DAO_CHECK(pUsers->get_Item(varIndex, &pUser));

        // Retrieve name for user nCurrentUser
        DAO_CHECK(pUser->get_Name(&V_BSTR(&varName)));

        CString strTemp = V_BSTRT(&varName);

        // If there is a match, change the password
        if (strTemp == strUserName)
        {
            COleVariant varOldPwd(strOldPassword, VT_BSTRT);
            COleVariant varNewPwd(strNewPassword, VT_BSTRT);

            DAO_CHECK(pUser->NewPassword(V_BSTR(&varOldPwd),
                V_BSTR(&varNewPwd)));

            TRACE("\t Password is changed\n");
        }
    }
    // Clean up: decrement the usage count
    // on the OLE objects
    pUser->Release();
    pUsers->Release();
    wsp.Close();
}

Zmiana hasła elementu . Plik MDB

Aby zmienić hasło elementu . Plik MDB, użyj następującej funkcji:

void SetDBPassword(LPCTSTR pDB,
    LPCTSTR pszOldPassword,
    LPCTSTR pszNewPassword)
{
    CDaoDatabase db;
    CString strConnect(_T(";pwd="));

    // the database must be opened as exclusive
    // to set a password
    db.Open(pDB, TRUE, FALSE, strConnect + pszOldPassword);

    COleVariant NewPassword(pszNewPassword, VT_BSTRT),
                OldPassword(pszOldPassword, VT_BSTRT);

    DAO_CHECK(db.m_pDAODatabase->NewPassword(V_BSTR(&OldPassword),
        V_BSTR(&NewPassword)));

    db.Close();
}

Zobacz też

Uwagi techniczne według numerów
Uwagi techniczne według kategorii