TN054:直接调用DAO,在使用MFC DAO类时
说明 |
---|
从 Visual C++ .NET 起,Visual C++ 环境和向导不再支持 DAO(不过提供了 DAO 类,仍可供您使用)。Microsoft 建议对新项目使用 OLE DB 模板 或 ODBC 和 MFC。DAO 只应用于维护现有的应用程序。 |
在使用 MFC DAO 数据库选件类时,可能会直接使用 DAO 的情况是必需的。通常,这不是这样,但是,MFC 提供一些帮助器 framework 实现执行直接调用 DAO 简单,在合并使用 MFC 选件类直接使用 DAO 调用时。执行直接调用 DAO MFC 托管 DAO 对象的方法应要求代码仅几行。如果需要创建和使用不受 MFC DAO 托管对象,则必须通过实际调用对象的 发布 完成有点更多工作。此方法声明解释您可能希望直接调用 DAO," MFC 帮助器可以执行帮助您以及如何使用 DAO OLE 接口。最后,此说明提供演示如何的一些示例函数调用 DAO 直接 DAO 安全功能。
执行直接调用 DAO 何时
执行直接 DAO 的最常见情况下调用发生,当需要刷新集合,或者在实现 MFC 时不是包装的功能。MFC 未显示的最重要的功能是安全。如果要实现安全功能,需要直接使用 DAO 用户和组对象。除安全外,MFC 不支持中只有几个其他 DAO 功能。其中包括记录集克隆和数据库重复功能以及一些延迟添加到 DAO。
DAO 和 MFC 中实现的简要概述
MFC 的包装 DAO 可以使用 DAO 可以通过处理许多细节,因此不必担心小的内容。这包括强类型,更简单的接口的初始化的 OLE、创建和管理 DAO 对象 (尤其是集合对象),错误检查和提供 (不 VARIANT 或 BSTR 参数)。可以执行直接调用 DAO 和还是利用这些功能。所有代码必须执行是直接调用 DAO 创建的所有对象的 发布 调用和不修改任何接口指针 MFC 能够在内部确定。例如,在中,除非您了解 所有 内部后果,不要修改"打开 CDaoRecordset 对象的 m_pDAORecordset 成员。您可能,但是,使用 m_pDAORecordset 接口直接调用 DAO 获取字段集合。在这种情况下不会修改 m_pDAORecordset 成员。在完对象后,您必须对字段集合对象的 发布。
对 DAO 的帮助器的声明调用更加容易。
帮助器提供调用 DAO 更易于是在内部在 MFC DAO 数据库选件类使用相同的帮助器。这些帮助器用于检查返回代码,当进行直接调用 DAO 时,记录调试输出,如果需要,检查预期错误并引发相应的异常。具有映射到这两个帮助器之一的两个基础 helper 函数和四个宏。最佳的声明与阅读代码。请参见 DAO_CHECK、DAO_CHECK_ERROR、DAO_CHECK_MEM和 DAO_TRACE 在 AFXDAO.H 查看宏,并查看 AfxDaoCheck 和 AfxDaoTrace 在 DAOCORE.CPP。
使用 DAO OLE 接口
每个对象的 OLE 接口 DAO 对象层次结构。标头文件 DBDAOINT.H 定义,在 \program files\Microsoft Visual Studio .NET 2003\VC7 找到 \include 目录。这些接口提供使您可以操作整个 DAO 层次结构的方法。
对于许多 DAO 接口的方法,则需要操作 BSTR 对象 (用于 OLE 自动化的一个长度为前缀的字符串)。BSTR 对象在 VARIANT 数据类型中通常是封装。MFC 选件类 COleVariant 从 VARIANT 数据类型继承。根据您是否生成 ANSI 或 Unicode 项目,DAO 接口将返回 ANSI 或 Unicode BSTRs。两个宏,V_BSTR 和 V_BSTRT,有助于确保清晰的 DAO 接口获取所需类型的 BSTR。
V_BSTR 中提取 COleVariant的 bstrVal 成员。此宏,如果需要传递 COleVariant 的内容添加到 DAO 接口的方法时,通常使用。下面的代码片段演示声明和实际使用利用 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 ) ));
监视 COleVariant 构造函数中指定 VT_BSTRT 参数上述确保在 COleVariant 的 ANSI BSTR,如果编译应用程序的 ANSI 版本和 Unicode BSTR 到应用程序的 Unicode 版本。这就是" DAO 需要。
另一个宏,V_BSTRT,根据生成的类型中提取 ANSI 或 COleVariant 的 Unicode bstrVal 成员 (ANSI 或 Unicode)。下面的代码演示如何从 COleVariant 提取 BSTR 值。CString:
COleVariant varName( _T( "MyName" ), VT_BSTRT );
CString str = V_BSTRT( &varName );
V_BSTRT 宏,与打开在 COleVariant存储的其他类型的其他技术协同,在 DAOVIEW 示例中所示。具体而言,此转换在 CCrack::strVARIANT 方法执行。此方法,如有可能,将 COleVariant 的值转换为 CString实例。
简单示例的直接调用 DAO
在刷新基础 DAO 集合对象时,是必需的情况可能会通常,则不应是必需的,但是,它是一个简单的程序,如果需要)。例如,如果集合可能需要刷新是,在对来创建新的 tabledefs 时的多个用户的多用户环境中。在您的 tabledefs 集合可能过时。若要刷新集合,需要调用特定集合对象的 刷新 方法和检查错误:
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 affect.
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->get_Count( &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();
}