在手头的一个项目中需要对某些历史库中的过期(超过一定时长)记录进行备份,但备份库可能是分布在其它服务器上的。因此不能简单地通过SELECT INTO 语句来进行处理,Google了一下也没找到什么好的办法,只好自己写代码进行处理。(另:由于此项目是用VC++开发,如果是用C#开发就好处理多了)
下面简要介绍一下实现过程,请高手指点。
1. 用到的一些配置变量:
COleDateTime m_dtLastClearTime; // 最后一次备份时间
int m_iHistoryOverdueDays; // 历史记录过期的天数
2. 实现流程
a. 判断是否需要进行备份(判断最后一次备份时间与当前时间差是否大于历史记录过期的天数,如果是则进行备份,否则退出不作备份)
b. 使用数据表创建脚本在备份数据库中创建备份数据表(备份表的命名约定:原表名+年月日)
c. 转移满足条件的数据
d. 删除原表中过期数据
3. 转移满足条件的数据的代码
1
HRESULT TransferHistoryRecords(const CString csTime, const CString csTableName, const CString csTimeFieldName)
2

{
3
try
4
{
5
CString csQuerySql = _T(""), csOverdueDays, csNewTableName;
6
csOverdueDays.Format(_T("%d"), m_iHistoryOverdueDays);
7
csNewTableName.Format(_T("%s_%s"), csTableName, csTime);
8
csQuerySql.Format(_T("SELECT * FROM %s "), csTableName);
9
csQuerySql += _T(" WHERE (") + csTimeFieldName + _T("<DATEADD(dd,-") + csOverdueDays + _T(",GETDATE()))");
10
}
11
12
AdoNS::_RecordsetPtr rsTt;
13
HRESULT hr = rsTt.CreateInstance(__uuidof(AdoNS::Recordset));
14
rsTt->CursorLocation=AdoNS::adUseClient;
15
hr = rsTt->Open(_bstr_t(csQuerySql),_variant_t((IDispatch *)m_objDbConn.m_pDbConnAlarm,true),AdoNS::adOpenDynamic,AdoNS::adLockUnspecified,AdoNS::adCmdText);
16
if (FAILED(hr))
17
{
18
CSasLog::WriteLog(_T("Ex050001: 历史数据库查询出错: ") + csTableName);
19
return E_FAIL;
20
}
21
22
AdoNS::FieldsPtr pFields;
23
rsTt->get_Fields(&pFields);
24
long iFieldCount = 0;
25
hr = pFields->get_Count(&iFieldCount);
26
if (FAILED(hr))
27
{
28
CSasLog::WriteLog(_T("Ex050002: 历史数据库查询出错: ") + csTableName);
29
rsTt->Close();
30
return E_FAIL;
31
}
32
33
AdoNS::_RecordsetPtr rsAn;
34
hr = rsAn.CreateInstance(__uuidof(AdoNS::Recordset));
35
rsAn->CursorLocation = AdoNS::adUseClient;
36
if ((m_objHistoryBackDbConnPrm.m_pDbConn != NULL) && (m_objHistoryBackDbConnPrm.m_pDbConn->State == 1))
37
{
38
hr = rsAn->Open(_bstr_t(csNewTableName), m_objHistoryBackDbConnPrm.m_pDbConn.GetInterfacePtr(), AdoNS::adOpenKeyset, AdoNS::adLockOptimistic, AdoNS::adCmdTable);
39
if (FAILED(hr))
40
{
41
CSasLog::WriteLog(_T("Ex050003: 打开备份历史数据库出错: ") + csNewTableName);
42
rsTt->Close();
43
return E_FAIL;
44
}
45
}
46
else
47
{
48
CSasLog::WriteLog(_T("Ex050004: 打开备份历史数据库出错: ") + csNewTableName);
49
rsTt->Close();
50
}
51
52
VARIANT vtIndex, vtValue;
53
vtIndex.vt = VT_I4;
54
vtIndex.intVal = 0;
55
long lAttribute = 0;
56
BSTR bstrFieldName;
57
58
while (! rsTt->adoEOF)
59
{
60
hr = rsAn->AddNew();
61
if (FAILED(hr))
62
{
63
break;
64
}
65
66
for(int i=0; i<iFieldCount; i++)
67
{
68
AdoNS::FieldPtr pField;
69
vtIndex.intVal = i;
70
pFields->get_Item(vtIndex, &pField);
71
lAttribute = 0;
72
pField->get_Attributes(&lAttribute);
73
if (lAttribute == 16)
74
{
75
continue;
76
}
77
78
pField->get_Value(&vtValue);
79
pField->get_Name(&bstrFieldName);
80
rsAn->PutCollect(bstrFieldName, vtValue);
81
}
82
83
rsAn->Update();
84
rsTt->MoveNext();
85
}
86
87
rsTt->Close();
88
}
89
catch(_com_error ex)
90
{
91
CSasLog::WriteLog(_T("TransferHistoryRecords[") + csTableName + _T("] error: ") + CString(ex.ErrorMessage()));
92
return E_FAIL;
93
}
94
95
return S_OK;
96
}
97
其它代码较为简单,在此就不贴出来了。