Sdílet prostřednictvím


TN054: Přímé volání rozhraní DAO při používání tříd DAO knihovny MFC

Poznámka

DaO se používá s databázemi Accessu a podporuje se prostřednictvím Office 2013. DAO 3.6 je konečná verze a je považována za za zastaralou. Prostředí a průvodci Visual C++ nepodporují rozhraní DAO (i když jsou zahrnuty třídy DAO a můžete je stále používat). Společnost Microsoft doporučuje pro nové projekty používat šablony OLE DB nebo rozhraní ODBC a MFC . DaO byste měli používat jenom při údržbě existujících aplikací.

Při použití databázových tříd MFC DAO může dojít k situacím, kdy je nutné přímo použít rozhraní DAO. Obvykle to nebude případ, ale MFC poskytuje některé pomocné mechanismy, které usnadňují jednoduché přímé volání DAO při kombinování použití tříd MFC s přímými voláními DAO. Přímé volání DAO metod objektu DAO spravovaného mfc by mělo vyžadovat pouze několik řádků kódu. Pokud potřebujete vytvořit a používat objekty DAO, které nejsou spravovány prostředím MFC, budete muset udělat o něco více práce tím, že objekt skutečně zavoláte Release . Tato technická poznámka vysvětluje, kdy můžete chtít volat rozhraní DAO přímo, co můžou pomoct pomoct pomoc pomoct pomoct a jak používat rozhraní DAO OLE. Nakonec tato poznámka obsahuje některé ukázkové funkce, které ukazují, jak volat DAO přímo pro funkce zabezpečení DAO.

Kdy provést přímé volání DAO

K nejběžnějším situacím při provádění přímých volání DAO dochází v případě, že je potřeba aktualizovat kolekce nebo když implementujete funkce, které nejsou zabalené prostředím MFC. Nejdůležitější funkcí, kterou mfc nezveřesní, je zabezpečení. Pokud chcete implementovat funkce zabezpečení, budete muset přímo použít objekty uživatelů a skupin DAO. Kromě zabezpečení existuje pouze několik dalších funkcí DAO, které mfc nepodporuje. Patří sem klonování sad záznamů a funkce replikace databáze a také několik pozdních doplňků daO.

Stručný přehled implementace rozhraní DAO a MFC

Zabalení rozhraní DAO mfc usnadňuje práci s dao tím, že zpracovává mnoho podrobností, takže si nemusíte dělat starosti s malými věcmi. To zahrnuje inicializaci OLE, vytvoření a správu objektů DAO (zejména objektů kolekce), kontrolu chyb a poskytnutí silného typu, jednoduššího rozhraní (bez variant nebo BSTR argumentů). Můžete provádět přímá volání DAO a stále využívat tyto funkce. Veškerý kód musí volat Release všechny objekty vytvořené přímým voláním DAO, a ne upravovat žádné ukazatele rozhraní, které mfc může spoléhat interně. Neupravujte například m_pDAORecordset člena otevřeného CDaoRecordset objektu, pokud nerozumíte všem interním důsledkům. Můžete však použít rozhraní m_pDAORecordset k volání DAO přímo pro získání kolekce Pole. V takovém případě se člen m_pDAORecordset nezmění. Jakmile s objektem skončíte, stačí volat Release objekt kolekce Pole.

Popis pomocných rutin, které usnadňují volání DAO

Pomocné rutiny poskytované k usnadnění volání DAO jsou stejné pomocné rutiny, které se používají interně v databázových třídách MFC DAO. Tyto pomocné rutiny slouží ke kontrole návratových kódů při provádění přímého volání DAO, protokolování výstupu ladění, kontrole očekávaných chyb a vyvolání příslušných výjimek v případě potřeby. Existují dvě základní pomocné funkce a čtyři makra, která se mapují na jeden z těchto dvou pomocných rutin. Nejlepším vysvětlením by bylo jednoduše přečíst kód. Viz DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM a DAO_TRACE v AFXDAO. H zobrazí makra a uvidíte AfxDaoCheck a AfxDaoTrace v DAOCORE. CPP.

Použití rozhraní DAO OLE

Rozhraní OLE pro každý objekt v hierarchii objektů DAO jsou definována v souboru hlaviček DBDAOINT. H, který se nachází v adresáři \Program Files\Microsoft Visual Studio .NET 2003\VC7\include. Tato rozhraní poskytují metody, které umožňují manipulovat s celou hierarchií DAO.

U mnoha metod v rozhraních DAO budete muset manipulovat s objektem BSTR (řetězec s předponou délky používaný v automatizaci OLE). Objekt BSTR je obvykle zapouzdřen v rámci datového typu VARIANT . Samotná třída COleVariant MFC dědí z datového typu VARIANT . V závislosti na tom, jestli sestavíte projekt pro ANSI nebo Unicode, vrátí rozhraní DAO anSI nebo Unicode BSTR. Dvě makra, V_BSTR a V_BSTRT, jsou užitečná pro zajištění, že rozhraní DAO získá BSTR očekávaný typ.

V_BSTR extrahuje člena bstrVal .COleVariant Toto makro se obvykle používá, když potřebujete předat obsah COleVariant metody rozhraní DAO. Následující fragment kódu ukazuje deklarace i skutečné použití pro dvě metody rozhraní DAO DAOUser, které využívají V_BSTR makro:

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

Všimněte si, že VT_BSTRT argument zadaný v COleVariant konstruktoru výše zajišťuje, že pokud sestavíte verzi aplikace ANSI a Unicode BSTR pro verzi Unicode vaší aplikace, bude k dispozici ANSI BSTR COleVariant. To je to, co DAO očekává.

Druhé makro, V_BSTRT, extrahuje buď člen COleVariant ANSI nebo Unicode bstrVal v závislosti na typu sestavení (ANSI nebo Unicode). Následující kód ukazuje, jak extrahovat BSTR hodnotu z do COleVariant CString:

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

Makro V_BSTRT spolu s dalšími technikami pro otevření jiných typů, které jsou uloženy COleVariant, je demonstrováno v ukázce DAOVIEW. Konkrétně se tento překlad provádí v CCrack::strVARIANT metodě. Tato metoda, pokud je to možné, přeloží hodnotu objektu COleVariant do instance CString.

Jednoduchý příklad přímého volání do DAO

Situace mohou nastat, když je nutné aktualizovat základní objekty kolekce DAO. Za normálních okolností by to nemělo být nutné, ale je to jednoduchý postup, pokud je to nutné. Příkladem, kdy může být potřeba aktualizovat kolekci, je při provozu v prostředí s více uživateli, kteří vytvářejí nové tabulky. V takovém případě může být kolekce tabledefs zastaralá. Pokud chcete kolekci aktualizovat, stačí volat metodu Refresh konkrétního objektu kolekce a zkontrolovat chyby:

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

Všimněte si, že v současné době jsou všechna rozhraní objektů kolekce DAO bezdokumentované podrobnosti implementace tříd databáze MFC DAO.

Použití rozhraní DAO přímo pro funkce zabezpečení DAO

Databázové třídy MFC DAO nezabalují funkce zabezpečení DAO. Abyste mohli používat některé funkce zabezpečení DAO, musíte volat metody rozhraní DAO. Následující funkce nastaví systémovou databázi a pak změní heslo uživatele. Tato funkce volá tři další funkce, které jsou následně definovány.

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

    // ...
}

Následující čtyři příklady ukazují, jak:

  • Nastavte systémovou databázi DAO (. MDW soubor).

  • Nastavte výchozího uživatele a heslo.

  • Změňte heslo uživatele.

  • Změňte heslo . SOUBOR MDB.

Nastavení systémové databáze

Níže je ukázková funkce pro nastavení systémové databáze, kterou bude aplikace používat. Tato funkce musí být volána před provedením dalších volání 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));
}

Nastavení výchozího uživatele a hesla

Pokud chcete nastavit výchozího uživatele a heslo pro systémovou databázi, použijte následující funkci:

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

Změna hesla uživatele

Pokud chcete změnit heslo uživatele, použijte následující funkci:

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

Změnaheslaho Soubor MDB

Změna hesla objektu . Soubor MDB použijte následující funkci:

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

Viz také

Technické poznámky podle čísel
Technické poznámky podle kategorií