TN054: DAO bei der Verwendung von MFC-DAO-Klassen direkt aufrufen

Hinweis

DAO wird mit Access-Datenbanken verwendet und wird über Office 2013 unterstützt. DAO 3.6 ist die letzte Version und gilt als veraltet. Die Visual C++-Umgebung und -Assistenten unterstützen DAO nicht (obwohl die DAO-Klassen enthalten sind und Sie sie weiterhin verwenden können). Microsoft empfiehlt, OLE DB-Vorlagen oder ODBC- und MFC für neue Projekte zu verwenden. Sie sollten DAO nur in Standard vorhandenen Anwendungen verwenden.

Wenn Sie die MFC DAO-Datenbankklassen verwenden, kann es Situationen geben, in denen es erforderlich ist, DAO direkt zu verwenden. In der Regel ist dies nicht der Fall, aber MFC hat einige Hilfsmechanismen bereitgestellt, um direkte DAO-Aufrufe einfach zu machen, wenn die Verwendung der MFC-Klassen mit direkten DAO-Aufrufen kombiniert wird. Direkte DAO-Aufrufe an die Methoden eines MFC-verwalteten DAO-Objekts sollten nur einige Codezeilen erfordern. Wenn Sie DAO-Objekte erstellen und verwenden müssen, die nicht von MFC verwaltet werden, müssen Sie etwas mehr Arbeit erledigen, indem Sie das Objekt tatsächlich aufrufenRelease. In diesem technischen Hinweis wird erläutert, wann Sie DAO direkt aufrufen möchten, was die MFC-Helfer tun können, um Ihnen zu helfen und wie Sie die DAO OLE-Schnittstellen verwenden. Schließlich enthält dieser Hinweis einige Beispielfunktionen, die zeigen, wie SIE DAO direkt für DAO-Sicherheitsfeatures aufrufen.

Wann direkte DAO-Anrufe getätigt werden sollen

Die häufigsten Situationen für direkte DAO-Aufrufe treten auf, wenn Sammlungen aktualisiert werden müssen oder wenn Sie Features implementieren, die nicht von MFC umschlossen werden. Das wichtigste Feature, das von MFC nicht verfügbar gemacht wird, ist Sicherheit. Wenn Sie Sicherheitsfeatures implementieren möchten, müssen Sie die DAO-Benutzer- und Gruppenobjekte direkt verwenden. Neben der Sicherheit gibt es nur ein paar andere DAO-Features, die von MFC nicht unterstützt werden. Dazu gehören Recordset-Kloning- und Datenbankreplikationsfeatures sowie einige späte Ergänzungen zu DAO.

Eine kurze Übersicht über die Implementierung von DAO und MFC

Der Umbruch von DAO von MFC erleichtert die Verwendung von DAO durch die Behandlung vieler Details, sodass Sie sich keine Gedanken über die kleinen Dinge machen müssen. Dazu gehören die Initialisierung von OLE, die Erstellung und Verwaltung der DAO-Objekte (insbesondere der Sammlungsobjekte), die Fehlerüberprüfung und die Bereitstellung einer stark typisierten, einfacheren Schnittstelle (keine VARIANT oder BSTR Argumente). Sie können direkte DAO-Anrufe tätigen und diese Features weiterhin nutzen. Der gesamte Code muss für alle Objekte aufgerufen Release werden, die durch direkte DAO-Aufrufe erstellt wurden, und keine Schnittstellenzeiger ändern, die MFC intern verwenden kann. Ändern Sie beispielsweise nicht das m_pDAORecordset Element eines geöffneten CDaoRecordset Objekts, es sei denn, Sie verstehen alle internen Auswirkungen. Sie können jedoch die m_pDAORecordset Schnittstelle verwenden, um DAO direkt aufzurufen, um die Fields-Auflistung abzurufen. In diesem Fall würde das m_pDAORecordset Mitglied nicht geändert. Sie müssen einfach das Fields-Auflistungsobjekt aufrufen Release , wenn Sie mit dem Objekt fertig sind.

Beschreibung der Helfer, um DAO-Anrufe zu vereinfachen

Die Hilfsprogramme, die bereitgestellt werden, um das Aufrufen von DAO zu vereinfachen, sind die gleichen Hilfsprogramme, die intern in den MFC DAO-Datenbankklassen verwendet werden. Diese Hilfsprogramme werden verwendet, um die Rückgabecodes bei einem direkten DAO-Aufruf zu überprüfen, die Debugausgabe zu protokollieren, auf erwartete Fehler zu prüfen und bei Bedarf geeignete Ausnahmen auszuwerfen. Es gibt zwei zugrunde liegende Hilfsfunktionen und vier Makros, die einem dieser beiden Hilfsprogramme zugeordnet sind. Die beste Erklärung wäre, einfach den Code zu lesen. Siehe DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM und DAO_TRACE in AFXDAO. H, um die Makros anzuzeigen, und siehe AfxDaoCheck und AfxDaoTrace in DAOCORE. CPP.

Verwenden der DAO-OLE-Schnittstellen

Die OLE-Schnittstellen für jedes Objekt in der DAO-Objekthierarchie werden in der Headerdatei DBDAOINT definiert. H, das im Verzeichnis \Programme\Microsoft Visual Studio .NET 2003\VC7\include enthalten ist. Diese Schnittstellen stellen Methoden bereit, mit denen Sie die gesamte DAO-Hierarchie bearbeiten können.

Für viele der Methoden in den DAO-Schnittstellen müssen Sie ein BSTR Objekt bearbeiten (eine längepräfixierte Zeichenfolge, die in der OLE-Automatisierung verwendet wird). Das BSTR Objekt wird in der Regel innerhalb des VARIANT-Datentyps gekapselt. Die MFC-Klasse COleVariant selbst erbt vom VARIANT-Datentyp . Je nachdem, ob Sie Ihr Projekt für ANSI oder Unicode erstellen, geben die DAO-Schnittstellen ANSI oder Unicode BSTRs zurück. Zwei Makros, V_BSTR und V_BSTRT, sind nützlich, um zu versichern, dass die DAO-Schnittstelle den BSTR erwarteten Typ erhält.

V_BSTR extrahiert das bstrVal-Element eines .COleVariant Dieses Makro wird in der Regel verwendet, wenn Sie den Inhalt einer COleVariant AN eine Methode einer DAO-Schnittstelle übergeben müssen. Das folgende Codefragment zeigt sowohl die Deklarationen als auch die tatsächliche Verwendung für zwei Methoden der DAO DAOUser-Schnittstelle, die das V_BSTR Makro nutzen:

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

Beachten Sie, dass das VT_BSTRT oben im COleVariant Konstruktor angegebene Argument sicherstellt, dass ein ANSI BSTR in der COleVariant ANSI-Version Ihrer Anwendung und ein Unicode für eine Unicode-Version BSTR Ihrer Anwendung vorhanden ist. Das erwartet DAO.

Das andere Makro, V_BSTRT, extrahiert entweder ein ANSI- oder Unicode-bstrVal-Element je COleVariant nach Buildtyp (ANSI oder Unicode). Der folgende Code veranschaulicht, wie der BSTR Wert aus einem in eins CStringCOleVariant extrahiert wird:

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

Das V_BSTRT Makro wird zusammen mit anderen Techniken zum Öffnen anderer Typen, die in COleVariantgespeichert sind, im DAOVIEW-Beispiel veranschaulicht. Insbesondere wird diese Übersetzung in der CCrack::strVARIANT Methode durchgeführt. Diese Methode übersetzt, sofern möglich, den Wert einer COleVariant in eine Instanz von CString.

Einfaches Beispiel für einen Direkten Anruf an DAO

Situationen können auftreten, wenn es erforderlich ist, die zugrunde liegenden DAO-Auflistungsobjekte zu aktualisieren. Normalerweise sollte dies nicht notwendig sein, aber es ist ein einfaches Verfahren, wenn es notwendig ist. Ein Beispiel dafür, wann eine Auflistung möglicherweise aktualisiert werden muss, ist die Verwendung in einer Mehrbenutzerumgebung mit mehreren Benutzern, die neue Tabledefs erstellen. In diesem Fall wird ihre Tabledefs-Auflistung möglicherweise veraltet. Um die Auflistung zu aktualisieren, müssen Sie einfach die Refresh Methode des jeweiligen Auflistungsobjekts aufrufen und auf Fehler überprüfen:

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

Beachten Sie, dass derzeit alle DAO-Auflistungsobjektschnittstellen nicht dokumentierte Implementierungsdetails der MFC DAO-Datenbankklassen sind.

Direktes Verwenden von DAO für DAO-Sicherheitsfeatures

Die MFC DAO-Datenbankklassen umschließen keine DAO-Sicherheitsfeatures. Sie müssen Methoden von DAO-Schnittstellen aufrufen, um einige DAO-Sicherheitsfeatures zu verwenden. Die folgende Funktion legt die Systemdatenbank fest und ändert dann das Kennwort des Benutzers. Diese Funktion ruft drei weitere Funktionen auf, die anschließend definiert werden.

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

    // ...
}

Die nächsten vier Beispiele veranschaulichen folgendes:

  • Legen Sie die DAO-Systemdatenbank (. MDW-Datei).

  • Legen Sie den Standardbenutzer und das Standardkennwort fest.

  • Ändern Sie das Kennwort eines Benutzers.

  • Ändern des Kennworts eines . MDB-Datei.

Festlegen der Systemdatenbank

Nachfolgend finden Sie eine Beispielfunktion zum Festlegen der Systemdatenbank, die von einer Anwendung verwendet wird. Diese Funktion muss aufgerufen werden, bevor andere DAO-Aufrufe ausgeführt werden.

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

Festlegen des Standardbenutzers und des Kennworts

Verwenden Sie die folgende Funktion, um den Standardbenutzer und das Kennwort für eine Systemdatenbank festzulegen:

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

Ändern des Kennworts eines Benutzers

Verwenden Sie die folgende Funktion, um das Kennwort eines Benutzers zu ändern:

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

Ändern des Kennworts eines . MDB-Datei

So ändern Sie das Kennwort einer . MDB-Datei verwenden Sie die folgende Funktion:

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

Siehe auch

Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet