Как прикрепить файл базы данных MDF с помощью OLEDB в C ++? - PullRequest
0 голосов
/ 20 января 2012

Мой код C ++ успешно восстанавливает файл резервной копии базы данных SqlServer, а затем извлекает необходимую информацию из полученной базы данных с помощью OLEDB API.

Вот мой код C ++, в конце которого я получаю IDBCreateCommand экземпляр готов к использованию для выполнения различных запросов к восстановленной базе данных:

DB::DB(LPCWSTR wszDataSource, LPCWSTR wszBackupFilePath, LPCWSTR wszRestoreFolderPath)
{
  fs::path backupFilePath = fs::canonical(wszBackupFilePath).make_preferred();
  fs::path restoreFolderPath = fs::canonical(wszRestoreFolderPath).make_preferred();
  std::wstring db = backupFilePath.leaf().stem().wstring();
  boost::wformat restoreQueryFmt(L"RESTORE DATABASE [%2%] FROM DISK = N'%1%' WITH REPLACE, STATS = 10, MOVE N'%2%' TO N'%3%\\%2%.mdf', MOVE N'%2%_log' TO N'%3%\\%2%.LDF'");
  std::wstring query = (restoreQueryFmt % backupFilePath.wstring() % db % restoreFolderPath.wstring()).str();

  IDBInitializePtr spDBInitialize;
  HRESULT hr = spDBInitialize.CreateInstance(CLSID_SQLNCLI10, NULL);
  if (REGDB_E_CLASSNOTREG == hr)
  {
    hr = spDBInitialize.CreateInstance(CLSID_SQLNCLI, NULL);
  }
  _HRESULT_CHECK3(spDBInitialize, hr);

  _variant_t vDataSource(wszDataSource);
  _variant_t vAuth(L"SSPI");

  DBPROP dbprop[2];          // property used in property set to initialize provider

  dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE;
  dbprop[0].dwOptions  = DBPROPOPTIONS_REQUIRED;
  dbprop[0].vValue = vDataSource;

  dbprop[1].dwPropertyID  = DBPROP_AUTH_INTEGRATED;
  dbprop[1].dwOptions = DBPROPOPTIONS_REQUIRED;
  dbprop[1].vValue = vAuth;

  DBPROPSET dbpropset[1];        // Property Set used to initialize provider
  dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
  dbpropset[0].rgProperties  = dbprop;
  dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]);

   // Set initialization properties.
  IDBPropertiesPtr spDBProperties = spDBInitialize;

  _HRESULT_CHECK(spDBProperties, SetProperties(1, dbpropset));
  _HRESULT_CHECK(spDBInitialize, Initialize());

  IDBCreateSessionPtr spCreateSession = spDBInitialize;
  _HRESULT_CHECK(spCreateSession, CreateSession(NULL, IID_IDBCreateCommand, reinterpret_cast<IUnknown **>(&m_spDBCreateCommand)));

  ICommandTextPtr spCommandText;
  _HRESULT_CHECK(m_spDBCreateCommand, CreateCommand(NULL, IID_ICommandText, reinterpret_cast<IUnknown **>(&spCommandText)));

  _HRESULT_CHECK(spCommandText, SetCommandText(DBGUID_SQL, query.c_str()));
  _HRESULT_CHECK(spCommandText, Execute(NULL, IID_NULL, NULL, NULL, NULL));
  _HRESULT_CHECK(spCommandText, SetCommandText(DBGUID_SQL, (boost::wformat(L"USE \"%1%\"") % db).str().c_str()));
  _HRESULT_CHECK(spCommandText, Execute(NULL, IID_NULL, NULL, NULL, NULL));
}

Что он делает:

  1. Инициализирует новое соединение с базой данных, используя заданный источник данных (например,". \ SQLEXPRESS") и интегрированная схема аутентификации SSPI.
  2. Выполняет оператор RESTORE DATABASE T-SQL, например: RESTORE DATABASE [my_db] FROM DISK = N'c:\temp\my_db.ebf' WITH REPLACE, STATS = 10, MOVE 'my_db' TO N'c:\temp\my_db.mdf', MOVE N'my_db_log' TO N'c:\temp\my_db.LDF'
  3. Использовать новую базу данных для последующих запросоввыполняется USE "my_db"

Итак, у меня нет проблем с восстановлением файла резервной копии базы данных и продолжением оттуда.

Теперь я столкнулся с другой проблемой.Предположим, что нет файла резервной копии, скорее, уже существующий файл MDF - как мне присоединить его с помощью API OLEDB C ++?

Спасибо.

РЕДАКТИРОВАНИЕ

Предполагается, что файл .mdf сопровождается всеми файлами, необходимыми ядру базы данных - .ldf и другими при необходимости.

1 Ответ

1 голос
/ 20 января 2012

Вы не можете присоединить базу данных, если у вас есть только файл MDF, потому что это, в лучшем случае, только половина базы данных. Вам нужен MD и LDF . И любые дополнительные файлы NDF или вторичные файлы LDF, составляющие исходную базу данных.

Предположим, у вас есть MDF и LDF как% 1% и% 3%, тогда все, что вам нужно сделать, это выполнить этот оператор:

CREATE DATABASE [%2%] 
  ON (FILENAME=N'%1%')
  , (FILENAME=N'%3')
  FOR ATTACH;

См. Как переместить базу данных с помощью отсоединения и присоединения (Transact-SQL)

Опция присоединения и только MDF существует (используйте FOR ATTACH_REBUILD_LOG), но она поставляется со многими предупреждениями, поскольку она работает только на чисто выключенной базе данных (в противном случае она может привести к повреждению базы данных). Нет возможности присоединить базу данных, если вам не хватает вторичных файлов NDF.

...