TN054: MFC DAO 클래스를 사용하면서 직접 DAO 호출

참고 항목

DAO는 Access 데이터베이스와 함께 사용되며 Office 2013을 통해 지원됩니다. DAO 3.6은 최종 버전이며 사용되지 않는 것으로 간주합니다. Visual C++ 환경 및 마법사는 DAO를 지원하지 않습니다(DAO 클래스가 포함되어 있고 계속 사용할 수 있지만). 새 프로젝트에는 OLE DB 템플릿 또는 ODBC 및 MFC를 사용하는 것이 좋습니다. 기존 애플리케이션에 기본 DAO만 사용해야 합니다.

MFC DAO 데이터베이스 클래스를 사용하는 경우 DAO를 직접 사용해야 하는 경우가 있을 수 있습니다. 일반적으로는 그렇지 않지만 MFC는 직접 DAO 호출과 MFC 클래스의 사용을 결합할 때 직접 DAO 호출을 간단하게 만드는 데 도움이 되는 몇 가지 도우미 메커니즘을 제공했습니다. MFC 관리형 DAO 개체의 메서드에 대한 직접 DAO 호출을 수행하려면 몇 줄의 코드만 있으면 됩니다. MFC에서 관리되지 않는 DAO 개체를 만들고 사용해야 하는 경우 실제로 개체를 호출 Release 하여 좀 더 많은 작업을 수행해야 합니다. 이 기술 참고에서는 DAO를 직접 호출하려는 경우, MFC 도우미가 도움을 주기 위해 수행할 수 있는 작업 및 DAO OLE 인터페이스를 사용하는 방법을 설명합니다. 마지막으로 이 참고에서는 DAO 보안 기능에 대해 DAO를 직접 호출하는 방법을 보여 주는 몇 가지 샘플 함수를 제공합니다.

직접 DAO 호출을 하는 경우

컬렉션을 새로 고쳐야 하거나 MFC에 의해 래핑되지 않은 기능을 구현하는 경우 직접 DAO 호출을 수행할 때 가장 일반적인 상황이 발생합니다. MFC에서 노출되지 않는 가장 중요한 기능은 보안입니다. 보안 기능을 구현하려면 DAO 사용자 및 Group 개체를 직접 사용해야 합니다. 보안 외에도 MFC에서 지원하지 않는 몇 가지 다른 DAO 기능만 있습니다. 여기에는 레코드 집합 복제 및 데이터베이스 복제본(replica)tion 기능뿐만 아니라 DAO에 대한 몇 가지 늦은 추가가 포함됩니다.

DAO 및 MFC 구현에 대한 간략한 개요

MFC의 DAO 래핑을 사용하면 많은 세부 정보를 처리하여 DAO를 더 쉽게 사용할 수 있으므로 작은 것에 대해 걱정할 필요가 없습니다. 여기에는 OLE 초기화, DAO 개체(특히 컬렉션 개체)의 생성 및 관리, 오류 검사 및 강력한 형식의 간단한 인터페이스 제공(VARIANT 또는 BSTR 인수 없음)이 포함됩니다. 직접 DAO 호출을 수행하고 이러한 기능을 계속 활용할 수 있습니다. 코드는 직접 DAO 호출로 만든 개체를 호출 Release 하고 MFC가 내부적으로 사용할 수 있는 인터페이스 포인터를 수정하지 않아야 합니다. 예를 들어 모든 내부 파급 효과를 이해하지 않는 한 열려 CDaoRecordset 있는 개체의 m_pDAORecordset 멤버를 수정하지 마세요. 그러나 m_pDAORecordset 인터페이스를 사용하여 DAO를 직접 호출하여 Fields 컬렉션을 가져올 수 있습니다. 이 경우 m_pDAORecordset 멤버는 수정되지 않습니다. 개체를 완료하면 Fields 컬렉션 개체를 호출 Release 하기만 하면 됩니다.

DAO 호출을 더 쉽게 만드는 도우미에 대한 설명

DAO 호출을 더 쉽게 하기 위해 제공되는 도우미는 MFC DAO 데이터베이스 클래스에서 내부적으로 사용되는 동일한 도우미입니다. 이러한 도우미는 직접 DAO 호출을 수행하고, 디버그 출력을 로깅하고, 예상 오류에 대한 검사, 필요한 경우 적절한 예외를 throw할 때 반환 코드를 검사 데 사용됩니다. 두 개의 기본 도우미 함수와 이 두 도우미 중 하나에 매핑되는 4개의 매크로가 있습니다. 가장 좋은 설명은 단순히 코드를 읽는 것입니다. AFXDAO에서 DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEMDAO_TRACE 참조하세요. H를 사용하여 매크로를 확인하고 DAOCORE에서 AfxDaoCheckAfxDaoTrace를 참조하세요. Cpp.

DAO OLE 인터페이스 사용

DAO 개체 계층 구조의 각 개체에 대한 OLE 인터페이스는 헤더 파일 DBDAOINT에 정의됩니다. H는 \Program Files\Microsoft Visual Studio .NET 2003\VC7\include 디렉터리에 있습니다. 이러한 인터페이스는 전체 DAO 계층 구조를 조작할 수 있는 메서드를 제공합니다.

DAO 인터페이스의 많은 메서드에서 개체(OLE 자동화에 사용되는 길이 접두사 문자열)를 조작 BSTR 해야 합니다. 개체는 BSTR 일반적으로 VARIANT 데이터 형식 내에 캡슐화됩니다. MFC 클래스 COleVariant 자체는 VARIANT 데이터 형식에서 상속됩니다. ANSI 또는 유니코드용 프로젝트를 빌드하는지 여부에 따라 DAO 인터페이스는 ANSI 또는 유니코드 BSTR를 반환합니다. V_BSTR 및 V_BSTRT 두 개의 매크로는 DAO 인터페이스가 예상 형식의 형식을 가져오는 BSTR 지 보장하는 데 유용합니다.

V_BSTR 의 bstrVal 멤버를 추출합니다COleVariant. 이 매크로는 일반적으로 DAO 인터페이스의 COleVariant 메서드에 내용을 전달해야 하는 경우에 사용됩니다. 다음 코드 조각에서는 V_BSTR 매크로를 활용하는 DAO DAOUser 인터페이스의 두 메서드에 대한 선언과 실제 사용을 모두 보여 줍니다.

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

VT_BSTRT 위의 생성자에 지정된 COleVariant 인수는 애플리케이션의 ANSI BSTR 버전과 애플리케이션의 유니코드 버전에 COleVariant 대한 유니코드 BSTR 를 빌드하는 경우 ANSI가 있는지 확인합니다. 이것이 DAO가 기대하는 것입니다.

V_BSTRT 다른 매크로는 빌드 유형(ANSI 또는 유니코드)에 따라 ANSI 또는 유니코드 bstrVal 멤버 COleVariant 를 추출합니다. 다음 코드에서는 값을 다음으로 추출 BSTR 하는 COleVariantCString방법을 보여 줍니다.

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

V_BSTRT 매크로는 저장된 다른 형식을 여는 다른 기술과 함께 DAOVIEW 샘플에 설명되어 있습니다 COleVariant. 특히 이 변환은 메서드에서 CCrack::strVARIANT 수행됩니다. 가능한 경우 이 메서드는 값을 인스턴스로 CString변환합니다COleVariant.

DAO에 대한 직접 호출의 간단한 예

기본 DAO 컬렉션 개체를 새로 고쳐야 하는 경우 상황이 발생할 수 있습니다. 일반적으로 이 작업은 필요하지 않지만 필요한 경우 간단한 절차입니다. 컬렉션을 새로 고쳐야 하는 경우의 예는 여러 사용자가 새 tabledef를 만드는 다중 사용자 환경에서 작동하는 경우입니다. 이 경우 tabledefs 컬렉션이 부실해질 수 있습니다. 컬렉션을 새로 고치려면 특정 컬렉션 개체의 메서드를 호출 Refresh 하고 오류를 검사 합니다.

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

현재 모든 DAO 컬렉션 개체 인터페이스는 MFC DAO 데이터베이스 클래스의 문서화되지 않은 구현 세부 정보입니다.

DAO 보안 기능에 DAO 직접 사용

MFC DAO 데이터베이스 클래스는 DAO 보안 기능을 래핑하지 않습니다. 일부 DAO 보안 기능을 사용하려면 DAO 인터페이스의 메서드를 호출해야 합니다. 다음 함수는 시스템 데이터베이스를 설정한 다음 사용자의 암호를 변경합니다. 이 함수는 이후에 정의된 세 가지 다른 함수를 호출합니다.

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

    // ...
}

다음 네 가지 예제에서는 다음 방법을 보여 줍니다.

  • 시스템 DAO 데이터베이스를 설정합니다(. MDW 파일).

  • 기본 사용자 및 암호를 설정합니다.

  • 사용자의 암호를 변경합니다.

  • 의 암호를 변경합니다. MDB 파일입니다.

시스템 데이터베이스 설정

다음은 애플리케이션에서 사용할 시스템 데이터베이스를 설정하는 샘플 함수입니다. 다른 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));
}

기본 사용자 및 암호 설정

시스템 데이터베이스에 대한 기본 사용자 및 암호를 설정하려면 다음 함수를 사용합니다.

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

사용자의 암호 변경

사용자의 암호를 변경하려면 다음 함수를 사용합니다.

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

의 암호 변경 MDB 파일

의 암호를 변경하려면 MDB 파일에서 다음 함수를 사용합니다.

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

참고 항목

번호별 기술 참고 사항
범주별 기술 참고 사항