【发布时间】:2012-01-21 03:35:44
【问题描述】:
我的 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));
}
它的作用是:
- 使用给定数据源(如“.\SQLEXPRESS”)和 SSPI 集成身份验证方案初始化新的数据库连接。
- 执行
RESTORE DATABASET-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' - 通过运行
USE "my_db"将新数据库用于后续查询
所以,我可以毫无问题地恢复数据库备份文件并从那里继续操作。
现在我面临另一个问题。假设没有备份文件,而是一个已经存在的 MDF 文件 - 如何使用 OLEDB C++ API 附加到它?
谢谢。
编辑
假设 .mdf 文件伴随着数据库引擎所需的所有文件 - .ldf 和其他需要的文件。
【问题讨论】:
标签: c++ sql-server oledb