将局域网内所有主机的SQL Server数据库备份到服务器 C++实现
时间: 2024-03-05 08:48:20 浏览: 111
C++连接SQL Server数据库
4星 · 用户满意度95%
以下是将局域网内所有主机的 SQL Server 数据库备份到服务器的 C++ 实现,需要使用 Windows API 中的 WMI (Windows Management Instrumentation) 和 OLE DB API:
```c++
#include <windows.h>
#include <comutil.h>
#include <atlbase.h>
#include <atlstr.h>
#include <sql.h>
#include <sqlext.h>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "comsuppw.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "odbc32.lib")
#pragma comment(lib, "odbccp32.lib")
#define SERVER_NAME "server_name"
#define SHARE_FOLDER_PATH "\\\\server_name\\share_folder\\"
#define BACKUP_EXTENSION ".bak"
int main()
{
// Initialize COM library
CoInitialize(NULL);
// Connect to WMI namespace
IWbemLocator* pLocator = NULL;
IWbemServices* pService = NULL;
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator);
if (SUCCEEDED(hr)) {
BSTR ns = SysAllocString(L"root\\Microsoft\\SqlServer\\ComputerManagement17");
hr = pLocator->ConnectServer(_bstr_t(ns), NULL, NULL, NULL, 0, NULL, NULL, &pService);
SysFreeString(ns);
}
if (SUCCEEDED(hr)) {
// Execute WQL query to get all SQL Server instances
BSTR query = SysAllocString(L"SELECT * FROM SqlServiceAdvancedProperty WHERE PropertyName = 'SqlServerInstanceName'");
IEnumWbemClassObject* pEnumerator = NULL;
hr = pService->ExecQuery(_bstr_t("WQL"), _bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
SysFreeString(query);
if (SUCCEEDED(hr)) {
// Traverse all instances and backup their databases
IWbemClassObject* pObject = NULL;
ULONG uCount = 0;
while (SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pObject, &uCount)) && uCount > 0) {
// Get instance name
VARIANT vtValue;
hr = pObject->Get(L"__RELPATH", 0, &vtValue, NULL, NULL);
if (SUCCEEDED(hr)) {
CString instanceName = vtValue.bstrVal;
instanceName.Replace(L"\\\\", L"");
instanceName.Replace(L"\"", L"");
instanceName.Replace(L"MSFT_SqlServiceAdvancedProperty.InstanceName=", L"");
instanceName.Replace(L",PropertyName=\"SqlServerInstanceName\"", L"");
instanceName.Replace(L"\\", L"_");
// Backup all databases
CString connectionString;
connectionString.Format(L"Provider=SQLOLEDB;Data Source=%s;Integrated Security=SSPI;", instanceName);
SQLHANDLE hEnv = NULL;
SQLHANDLE hConn = NULL;
SQLHANDLE hStmt = NULL;
SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
ret = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
ret = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
SQLCHAR szConnStrOut[1024];
SQLSMALLINT cbConnStrOut;
ret = SQLDriverConnect(hConn, NULL, (SQLCHAR*)(LPCWSTR) connectionString, (SQLSMALLINT) connectionString.GetLength(), szConnStrOut, 1024, &cbConnStrOut, SQL_DRIVER_NOPROMPT);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
SQLCHAR szSqlStr[1024];
SQLSMALLINT cbSqlStr;
SQLCHAR tableName[128];
SQLSMALLINT cbTableName;
SQLCHAR backupPath[1024];
SQLSMALLINT cbBackupPath;
SQLCHAR backupStatement[1024];
SQLSMALLINT cbBackupStatement;
SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
SQLExecDirect(hStmt, (SQLCHAR*)"SELECT name FROM sys.databases WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb')", SQL_NTS);
while (SQLFetch(hStmt) == SQL_SUCCESS) {
SQLGetData(hStmt, 1, SQL_C_CHAR, tableName, 128, &cbTableName);
CString backupFileName;
backupFileName.Format(L"%s%s%s", SHARE_FOLDER_PATH, (LPCWSTR) tableName, BACKUP_EXTENSION);
CString backupFilePath = backupFileName.Mid(2);
backupFilePath.Replace(L"\\", L"\\\\");
sprintf_s((char*) backupPath, sizeof(backupPath), "%ls", (LPCWSTR) backupFilePath);
sprintf_s((char*) backupStatement, sizeof(backupStatement), "BACKUP DATABASE [%s] TO DISK = '%s' WITH INIT", tableName, backupPath);
ret = SQLExecDirect(hStmt, backupStatement, SQL_NTS);
}
SQLFreeStmt(hStmt, SQL_CLOSE);
}
SQLDisconnect(hConn);
}
SQLFreeHandle(SQL_HANDLE_DBC, hConn);
}
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}
VariantClear(&vtValue);
}
pObject->Release();
pObject = NULL;
uCount = 0;
}
pEnumerator->Release();
}
pService->Release();
}
pLocator->Release();
// Clean up COM library
CoUninitialize();
return 0;
}
```
在代码中,需要将 `SERVER_NAME` 替换为服务器名称,`SHARE_FOLDER_PATH` 替换为共享文件夹路径,`BACKUP_EXTENSION` 替换为备份文件的扩展名。该代码会遍历所有 SQL Server 实例,并备份它们的所有数据库到共享文件夹中。注意,需要使用管理员权限运行程序。
阅读全文