Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
DAO используется с базами данных Access и поддерживается до Office 2013. DAO 3.6 является окончательной версией, и считается устаревшей. Среда разработки и мастера Visual C++ не поддерживают DAO, хотя классы DAO включены, и их можно использовать. Корпорация Майкрософт рекомендует использовать шаблоны OLE DB или ODBC и MFC для новых проектов. Для обслуживания существующих приложений следует использовать только DAO.
При использовании классов баз данных DAO MFC могут возникнуть ситуации, когда необходимо использовать DAO напрямую. Как правило, это не так, но MFC предоставил некоторые вспомогательные механизмы для упрощения прямых вызовов DAO при сочетании использования классов MFC с прямыми вызовами DAO. Выполнение прямых вызовов DAO к методам объекта DAO, управляемого MFC, должно требовать только несколько строк кода. Если вам нужно создать и использовать объекты DAO, которые не управляются MFC, вам придется проделать немного больше работы, фактически вызвав метод Release
на объекте. В этой технической заметке объясняется, когда может потребоваться напрямую вызвать DAO, какие вспомогательные средства MFC могут помочь вам и как использовать интерфейсы OLE DAO. Наконец, эта заметка содержит некоторые примеры функций, показывающих, как вызывать DAO напрямую для функций безопасности DAO.
Когда делать прямые вызовы DAO
Наиболее частые случаи выполнения прямых вызовов DAO возникают, когда коллекции необходимо обновить или при реализации возможностей, не упакованных MFC. Наиболее важным компонентом, не предоставляемым MFC, является безопасность. Если вы хотите реализовать функции безопасности, необходимо напрямую использовать объекты DAO User(s) и Group(s). Помимо безопасности, существует только несколько других функций DAO, которые не поддерживаются MFC. К ним относятся функции клонирования наборов записей и репликации баз данных, а также несколько поздних добавлений в DAO.
Краткий обзор реализации DAO и MFC
Оболочка MFC для DAO упрощает его использование, заботясь о многих деталях, чтобы вам не приходилось беспокоиться о мелочах. Это включает инициализацию OLE, создание и управление объектами DAO (особенно объектами коллекции), проверкой ошибок и предоставлением строго типизированного, простого интерфейса (без VARIANT или BSTR
аргументов). Вы можете выполнять прямые вызовы DAO и по-прежнему использовать эти функции. Весь ваш код должен только вызывать Release
для любых объектов, созданных прямыми вызовами DAO, и не изменять какие-либо интерфейсные указатели, на которые MFC может полагаться внутренне. Например, не изменяйте элемент m_pDAORecordset открытого CDaoRecordset
объекта, если вы не понимаете все внутренние последствия. Однако можно использовать интерфейс m_pDAORecordset для вызова DAO напрямую для получения коллекции Fields. В этом случае элемент m_pDAORecordset не будет изменен. Просто вызовите Release
для объекта коллекции Fields, когда закончите работать с объектом.
Описание вспомогательных функций для упрощения вызовов DAO
Вспомогательные средства, предоставляемые для упрощения вызова DAO, являются теми же вспомогательными средствами, которые используются внутренне в классах базы данных DAO MFC. Эти вспомогательные средства используются для проверки кодов возврата при выполнении прямого вызова DAO, ведения журнала выходных данных отладки, проверки ожидаемых ошибок и создания соответствующих исключений при необходимости. Существует две базовые вспомогательные функции и четыре макроса, которые сопоставляются с одним из этих двух вспомогательных элементов. Лучшее объяснение — это просто прочитать код. См. DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM и DAO_TRACE в AFXDAO. H, чтобы просмотреть макросы и просмотреть AfxDaoCheck и AfxDaoTrace в DAOCORE. CPP.
Использование интерфейсов OLE DAO
Интерфейсы OLE для каждого объекта в иерархии объектов DAO определяются в файле заголовка DBDAOINT. H, который находится в каталоге \Program Files\Microsoft Visual Studio .NET 2003\VC7\include. Эти интерфейсы предоставляют методы, позволяющие управлять всей иерархией DAO.
Для многих методов в интерфейсах DAO необходимо манипулировать BSTR
объектом (строка с префиксом длины, использующаяся в автоматизации OLE). Объект BSTR
обычно инкапсулируется в типе данных VARIANT . Класс COleVariant
MFC наследует от типа данных VARIANT . В зависимости от того, будете ли вы собирать проект для ANSI или Unicode, интерфейсы DAO будут возвращать ANSI или Unicode BSTR
. Два макроса, V_BSTR и V_BSTRT, полезны для обеспечения того, чтобы интерфейс DAO получал BSTR
ожидаемого типа.
V_BSTR извлекает элемент COleVariant
объекта. Этот макрос обычно используется, когда необходимо передать содержимое COleVariant
в метод интерфейса DAO. В следующем фрагменте кода показаны объявления и фактическое использование для двух методов интерфейса DAO DAOUser, который использует преимущества макроса 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)));
Обратите внимание, что аргумент VT_BSTRT
, указанный в вышеупомянутом конструкторе COleVariant
, гарантирует наличие ANSI BSTR
в COleVariant
, если вы собираете версию ANSI вашего приложения, и Unicode BSTR
для версии Unicode вашего приложения. Это то, что ожидает DAO.
Другой макрос, V_BSTRT, извлекает член ANSI или Юникод COleVariant
в зависимости от типа сборки (ANSI или Юникод). В следующем коде показано, как извлечь значение из BSTR
в COleVariant
:
COleVariant varName(_T("MyName"), VT_BSTRT);
CString str = V_BSTRT(&varName);
Макрос V_BSTRT, а также другие методы открытия других типов, хранящихся в COleVariant
, демонстрируются в примере DAOVIEW. В частности, этот перевод выполняется в методе CCrack::strVARIANT
. Этот метод, где это возможно, преобразует значение объекта COleVariant
в экземпляр CString
.
Простой пример прямого вызова к DAO
Ситуации могут возникнуть, когда необходимо обновить базовые объекты коллекции DAO. Как правило, это не обязательно, но это простая процедура, если это необходимо. Пример того, когда обновление коллекции может потребоваться, — это работа в многопользовательской среде с несколькими пользователями, которые создают новые определения таблиц. В этом случае коллекция tabledefs может устареть. Чтобы обновить коллекцию, необходимо просто вызвать Refresh
метод определенного объекта коллекции и проверить наличие ошибок:
DAO_CHECK(pMyDaoDatabase->m_pDAOTableDefs->Refresh());
Обратите внимание, что в настоящее время все интерфейсы объектов коллекций DAO являются незадокументированными деталями реализации классов баз данных DAO MFC.
Использование DAO непосредственно для функций безопасности DAO
Классы баз данных DAO MFC не упаковывают функции безопасности 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();
}
См. также
Технические примечания по номеру
Технические заметки по категориям