AdoRecordSet.cpp
上传用户:xutong0099
上传日期:2009-03-19
资源大小:29k
文件大小:87k
源码类别:

数据库系统

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "AdoRecordSet.h"
  3. #include <math.h>
  4. #include <io.h>
  5. #ifdef _DEBUG
  6. #undef THIS_FILE
  7. static char THIS_FILE[]=__FILE__;
  8. #define new DEBUG_NEW
  9. #endif
  10. /*########################################################################
  11.  ------------------------------------------------
  12. CAdoRecordSet class 构造/析构函数
  13.  ------------------------------------------------
  14.   ########################################################################*/
  15. CAdoRecordSet::CAdoRecordSet()
  16. {
  17. m_pConnection = NULL;
  18. m_SearchDirection = adSearchForward;
  19. m_pRecordset.CreateInstance("ADODB.Recordset");
  20. #ifdef _DEBUG
  21. if (m_pRecordset == NULL)
  22. {
  23. AfxMessageBox("RecordSet 对象创建失败! 请确认是否初始化了COM环境.");
  24. }
  25. #endif
  26. ASSERT(m_pRecordset != NULL);
  27. }
  28. CAdoRecordSet::CAdoRecordSet(CAdoConnection *pConnection)
  29. {
  30. m_SearchDirection = adSearchForward;
  31. m_pConnection = pConnection;
  32. ASSERT(m_pConnection != NULL);
  33. m_pRecordset.CreateInstance("ADODB.Recordset");
  34. #ifdef _DEBUG
  35. if (m_pRecordset == NULL)
  36. {
  37. AfxMessageBox("RecordSet 对象创建失败! 请确认是否初始化了COM环境.");
  38. }
  39. #endif
  40. ASSERT(m_pRecordset != NULL);
  41. }
  42. CAdoRecordSet::~CAdoRecordSet()
  43. {
  44. Release();
  45. }
  46. /*========================================================================
  47. Params:
  48. - strSQL: SQL语句, 表名, 存储过程调用或持久 Recordset 文件名.
  49. - CursorType:   可选. CursorTypeEnum 值, 确定打开 Recordset 时应该
  50. 使用的游标类型. 可为下列常量之一.
  51. [常量] [说明] 
  52. -----------------------------------------------
  53. adOpenForwardOnly 打开仅向前类型游标. 
  54. adOpenKeyset 打开键集类型游标. 
  55. adOpenDynamic 打开动态类型游标. 
  56. adOpenStatic 打开静态类型游标. 
  57. -----------------------------------------------
  58. - LockType:     可选, 确定打开 Recordset 时应该使用的锁定类型(并发)
  59. 的 LockTypeEnum 值, 可为下列常量之一.
  60. [常量] [说明] 
  61. -----------------------------------------------
  62. adLockReadOnly 只读 - 不能改变数据. 
  63. adLockPessimistic 保守式锁定 - 通常通过在编辑时立即锁定数据源的记录. 
  64. adLockOptimistic 开放式锁定 - 只在调用 Update 方法时才锁定记录. 
  65. adLockBatchOptimistic 开放式批更新 - 用于批更新模式(与立即更新模式
  66. 相对). 
  67. -----------------------------------------------
  68. - lOption 可选. 长整型值, 用于指示 strSQL 参数的类型. 可为下
  69. 列常量之一.
  70. [常量] [说明] 
  71. -------------------------------------------------
  72. adCmdText 指示strSQL为命令文本, 即普通的SQL语句. 
  73. adCmdTable 指示ADO生成SQL查询返回以 strSQL 命名的表中的
  74. 所有行. 
  75. adCmdTableDirect 指示所作的更改在strSQL中命名的表中返回所有行. 
  76. adCmdStoredProc 指示strSQL为存储过程. 
  77. adCmdUnknown 指示strSQL参数中的命令类型为未知. 
  78. adCmdFile 指示应从在strSQL中命名的文件中恢复保留(保存的)
  79. Recordset. 
  80. adAsyncExecute 指示应异步执行strSQL. 
  81. adAsyncFetch 指示在提取 Initial Fetch Size 属性中指定的初始
  82. 数量后, 应该异步提取所有剩余的行. 如果所需的行尚未
  83. 提取, 主要的线程将被堵塞直到行重新可用. 
  84. adAsyncFetchNonBlocking 指示主要线程在提取期间从未堵塞. 如果所请求
  85. 的行尚未提取, 当前行自动移到文件末尾. 
  86. ==========================================================================*/
  87. BOOL CAdoRecordSet::Open(LPCTSTR strSQL, long lOption, CursorTypeEnum CursorType, LockTypeEnum LockType)
  88. {
  89. ASSERT(m_pConnection != NULL);
  90. ASSERT(m_pRecordset != NULL);
  91. ASSERT(AfxIsValidString(strSQL));
  92. if(strcmp(strSQL, _T("")) != 0)
  93. {
  94. m_strSQL = strSQL;
  95. }
  96. if (m_pConnection == NULL || m_pRecordset == NULL)
  97. {
  98. return FALSE;
  99. }
  100. if (m_strSQL.IsEmpty())
  101. {
  102. ASSERT(FALSE);
  103. return FALSE;
  104. }
  105. try
  106. {
  107. if (IsOpen()) Close();
  108. return SUCCEEDED(m_pRecordset->Open(_variant_t(LPCTSTR(m_strSQL)), 
  109. _variant_t((IDispatch*)m_pConnection->GetConnection(), true),
  110. CursorType, LockType, lOption));
  111. }
  112. catch (_com_error e)
  113. {
  114. TRACE(_T("Warning: 打开记录集发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  115. TRACE(_T("%srn"), GetLastError());
  116. return FALSE;
  117. }
  118. }
  119. /*========================================================================
  120. Name: 通过重新执行对象所基于的查询, 更新 Recordset 对象中的数据.
  121.     ----------------------------------------------------------
  122. Params: Options   可选. 指示影响该操作选项的位屏蔽. 如果该参数设置
  123. 为 adAsyncExecute, 则该操作将异步执行并在它结束时产生 
  124. RecordsetChangeComplete 事件
  125.     ----------------------------------------------------------
  126. Remarks: 通过重新发出原始命令并再次检索数据, 可使用 Requery 方法刷新
  127. 来自数据源的 Recordset 对象的全部内容. 调用该方法等于相继调用 Close 和 
  128. Open 方法. 如果正在编辑当前记录或者添加新记录将产生错误.
  129. ==========================================================================*/
  130. BOOL CAdoRecordSet::Requery(long Options)
  131. {
  132. ASSERT(m_pRecordset != NULL);
  133. try
  134. {
  135. if (m_pRecordset != NULL) 
  136. {
  137. return (m_pRecordset->Requery(Options) == S_OK);
  138. }
  139. }
  140. catch (_com_error e)
  141. {
  142. TRACE(_T("Warning: Requery 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  143. return FALSE;
  144. return FALSE; 
  145. }
  146. /*========================================================================
  147. Name: 从基本数据库刷新当前 Recordset 对象中的数据.
  148.     ----------------------------------------------------------
  149. Params: AffectRecords:   可选, AffectEnum 值, 决定 Resync 方法所影
  150. 响的记录数目, 可以为下列常量之一.
  151. [常量] [说明]
  152. ------------------------------------
  153. adAffectCurrent 只刷新当前记录. 
  154. adAffectGroup 刷新满足当前 Filter 属性设置的记录.只有将 Filter
  155. 属性设置为有效预定义常量之一才能使用该选项. 
  156. adAffectAll 默认值.刷新 Recordset 对象中的所有记录, 包括由
  157. 于当前 Filter 属性设置而隐藏的记录. 
  158. adAffectAllChapters 刷新所有子集记录. 
  159. ResyncValues:   可选, ResyncEnum 值. 指定是否覆盖基本值. 可为下列
  160. 常量之一.
  161. [常量] [说明] 
  162. ------------------------------------
  163. adResyncAllValues 默认值. 覆盖数据, 取消挂起的更新. 
  164. adResyncUnderlyingValues 不覆盖数据, 不取消挂起的更新. 
  165.     ----------------------------------------------------------
  166. Remarks: 使用 Resync 方法将当前 Recordset 中的记录与基本的数据库重新
  167. 同步. 这在使用静态或仅向前的游标但希望看到基本数据库中的改动时十分有用.
  168. 如果将 CursorLocation 属性设置为 adUseClient, 则 Resync 仅对非只读的 
  169. Recordset 对象可用.
  170. 与 Requery 方法不同, Resync 方法不重新执行 Recordset 对象的基本的命令, 
  171. 基本的数据库中的新记录将不可见.
  172. ==========================================================================*/
  173. BOOL CAdoRecordSet::Resync(AffectEnum AffectRecords, ResyncEnum ResyncValues)
  174. {
  175. ASSERT(m_pRecordset != NULL);
  176. try
  177. {
  178. if (m_pRecordset != NULL) 
  179. {
  180. return (m_pRecordset->Resync(AffectRecords, ResyncValues) == S_OK);
  181. }
  182. }
  183. catch (_com_error e)
  184. {
  185. TRACE(_T("Warning: Resync 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  186. return FALSE;
  187. return FALSE; 
  188. }
  189. /*========================================================================
  190. Name: 将 Recordset 保存在持久性文件中.
  191.     ----------------------------------------------------------
  192. Params:
  193. [strFileName]:   可选. 文件的完整路径名, 用于保存 Recordset.
  194. [PersistFormat]:   可选. PersistFormatEnum 值, 指定保存 Recordset 所使
  195. 用的格式. 可以是如下的某个常量: 
  196. [常量] [说明] 
  197. ------------------------------
  198. adPersistADTG 使用专用的"Advanced Data Tablegram"格式保存. 
  199. adPersistXML (默认)使用 XML 格式保存. 
  200.     ----------------------------------------------------------
  201. Remarks: 只能对打开的 Recordset 调用 Save 方法. 随后使用 Load 方法可
  202. 以从文件中恢复 Recordset. 如果 Filter 属性影响 Recordset, 将只保存经过
  203. 筛选的行.
  204. 在第一次保存 Recordset 时指定 FileName. 如果随后调用 Save 时, 应忽
  205. 略 FileName, 否则将产生运行时错误. 如果随后使用新的 FileName 调用 Save, 
  206. 那么 Recordset 将保存到新的文件中, 但新文件和原始文件都是打开的.
  207. ==========================================================================*/
  208. BOOL CAdoRecordSet::Save(LPCTSTR strFileName, PersistFormatEnum PersistFormat)
  209. {
  210. ASSERT(m_pRecordset != NULL);
  211. ASSERT(IsOpen());
  212. if (m_strFileName == strFileName)
  213. {
  214. strFileName = NULL;
  215. }
  216. else if(_taccess(strFileName, 0) != -1)
  217. {
  218. DeleteFile(strFileName);
  219. m_strFileName = strFileName;
  220. }
  221. else
  222. {
  223. m_strFileName = strFileName;
  224. }
  225. try
  226. {
  227. if (m_pRecordset != NULL) 
  228. {
  229. return (m_pRecordset->Save(_bstr_t(strFileName), PersistFormat) == S_OK);
  230. }
  231. }
  232. catch (_com_error e)
  233. {
  234. TRACE(_T("Warning: Save 发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  235. return FALSE;
  236. return FALSE;
  237. }
  238. BOOL CAdoRecordSet::Load(LPCTSTR strFileName)
  239. {
  240. if (IsOpen()) Close();
  241. try
  242. {
  243. return (m_pRecordset->Open(strFileName, "Provider=MSPersist;", adOpenForwardOnly, adLockOptimistic, adCmdFile) == S_OK);
  244. }
  245. catch (_com_error &e)
  246. {
  247. TRACE(_T("Warning: Load 发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  248. return FALSE;
  249. }
  250. }
  251. /*========================================================================
  252. Name: 取消执行挂起的异步 Execute 或 Open 方法的调用.
  253. -----------------------------------------------------
  254. Remarks: 使用 Cancel 方法终止执行异步 Execute 或 Open 方法调用(即通
  255. 过 adAsyncConnect、adAsyncExecute 或 adAsyncFetch 参数调用的方法).
  256. 如果在试图终止的方法中没有使用 adAsyncExecute, 则 Cancel 将返回运行
  257. 时错误.
  258. ==========================================================================*/
  259. BOOL CAdoRecordSet::Cancel()
  260. {
  261. ASSERT(m_pRecordset != NULL);
  262. try
  263. {
  264. return m_pRecordset->Cancel();
  265. }
  266. catch (_com_error e)
  267. {
  268. TRACE(_T("Warning: Cancel发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  269. return FALSE;
  270. return FALSE;
  271. }
  272. /*========================================================================
  273. Name: 关闭打开的对象及任何相关对象.
  274. -----------------------------------------------------
  275. Remarks: 使用 Close 方法可关闭 Recordset 对象以便释放所有关联的系统
  276. 资源. 关闭对象并非将它从内存中删除, 可以更改它的属性设置并且在此后
  277. 再次打开. 要将对象从内存中完全删除, 可将对象变量设置为 NULL.
  278. 如果正在立即更新模式下进行编辑, 调用Close方法将产生错误,应首先
  279. 调用 Update 或 CancelUpdat 方法. 如果在批更新期间关闭 Recordset 对
  280. 象, 则自上次 UpdateBatch 调用以来所做的修改将全部丢失.
  281. 如果使用 Clone 方法创建已打开的 Recordset 对象的副本, 关闭原始
  282. Recordset或其副本将不影响任何其他副本.
  283. ==========================================================================*/
  284. void CAdoRecordSet::Close()
  285. {
  286. try
  287. {
  288. if (m_pRecordset != NULL && m_pRecordset->State != adStateClosed)
  289. {
  290. if (GetEditMode() == adEditNone) CancelUpdate();
  291. m_pRecordset->Close();
  292. }
  293. }
  294. catch (const _com_error& e)
  295. {
  296. TRACE(_T("Warning: 关闭记录集发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  297. }
  298. }
  299. /*========================================================================
  300. Name: 关闭连接并释放对象.
  301. -----------------------------------------------------
  302. Remarks: 关闭连接并释放CAdoRecordSet对象, 这样基本上从内容中完全清除了
  303. CAdoRecordSet对象.
  304. ==========================================================================*/
  305. void CAdoRecordSet::Release()
  306. {
  307. if (IsOpen()) Close();
  308. m_pRecordset.Release();
  309. m_pRecordset = NULL;
  310. }
  311. /*########################################################################
  312.   ------------------------------------------------
  313.    记录集更新操作
  314.   ------------------------------------------------
  315.   ########################################################################*/
  316. /*========================================================================
  317. Remarks: 开始添加新的纪录. 
  318. ==========================================================================*/
  319. BOOL CAdoRecordSet::AddNew()
  320. {
  321. ASSERT(m_pRecordset != NULL);
  322. try
  323. {
  324. if (m_pRecordset != NULL) 
  325. {
  326. if (m_pRecordset->AddNew() == S_OK)
  327. {
  328. return TRUE;
  329. }
  330. }
  331. }
  332. catch (_com_error e)
  333. {
  334. TRACE(_T("Warning: AddNew 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  335. return FALSE;
  336. return FALSE;
  337. }
  338. /*========================================================================
  339. Remarks: 在调用 AddNew 等方法后, 调用此方法完成更新或修改.
  340. ==========================================================================*/
  341. BOOL CAdoRecordSet::Update()
  342. {
  343. ASSERT(m_pRecordset != NULL);
  344. try
  345. {
  346. if (m_pRecordset != NULL) 
  347. {
  348. if (m_pRecordset->Update() == S_OK)
  349. {
  350. return TRUE;
  351. }
  352. }
  353. }
  354. catch (_com_error e)
  355. {
  356. TRACE(_T("Warning: Update 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  357. }
  358. CancelUpdate();
  359. return FALSE;
  360. }
  361. /*========================================================================
  362. Name: 将所有挂起的批更新写入磁盘.
  363.     ----------------------------------------------------------
  364. Params: AffectRecords   可选, AffectEnum 值. 决定 UpdateBatch 方法
  365. 所影响的记录数目.可以为如下常量之一.
  366. [常量] [说明] 
  367. ------------------------------------
  368. adAffectCurrent 只写入当前记录的挂起更改. 
  369. adAffectGroup 写入满足当前 Filter 属性设置的记录所发生的挂起
  370. 更改. 必须将 Filter 属性设置为某个有效的预定义常量才能使用该选项. 
  371. adAffectAll (默认值). 写入 Recordset 对象中所有记录的挂起
  372. 更改, 包括由于当前 Filter 属性设置而隐藏的任何记录. 
  373. adAffectAllChapters 写入所有子集的挂起更改. 
  374.     ----------------------------------------------------------
  375. Remarks: 按批更新模式修改 Recordset 对象时, 使用 UpdateBatch 方法可
  376. 将 Recordset 对象中的所有更改传递到基本数据库.
  377. 如果 Recordset 对象支持批更新, 那么可以将一个或多个记录的多重更改缓存在
  378. 本地, 然后再调用 UpdateBatch 方法. 如果在调用 UpdateBatch 方法时正在编
  379. 辑当前记录或者添加新的记录, 那么在将批更新传送到提供者之前, ADO 将自动
  380. 调用 Update 方法保存对当前记录的所有挂起更改.
  381.    只能对键集或静态游标使用批更新.
  382. ==========================================================================*/
  383. BOOL CAdoRecordSet::UpdateBatch(AffectEnum AffectRecords)
  384. {
  385. ASSERT(m_pRecordset != NULL);
  386. try
  387. {
  388. if (m_pRecordset != NULL) 
  389. {
  390. return (m_pRecordset->UpdateBatch(AffectRecords) == S_OK);
  391. }
  392. }
  393. catch (_com_error e)
  394. {
  395. TRACE(_T("Warning: UpdateBatch 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  396. return FALSE;
  397. return FALSE; 
  398. }
  399. /*========================================================================
  400. Name: 取消在调用 Update 方法前对当前记录或新记录所作的任何更改.
  401. -----------------------------------------------------
  402. Remarks: 使用 CancelUpdate 方法可取消对当前记录所作的任何更改或放弃
  403. 新添加的记录. 在调用 Update 方法后将无法撤消对当前记录或新记录所做的更
  404. 改, 除非更改是可以用 RollbackTrans 方法回卷的事务的一部分, 或者是可以
  405. 用 CancelBatch 方法取消的批更新的一部分.
  406. 如果在调用 CancelUpdate 方法时添加新记录, 则调用 AddNew 之前的当前
  407. 记录将再次成为当前记录.
  408. 如果尚未更改当前记录或添加新记录, 调用 CancelUpdate 方法将产生错误.
  409. ==========================================================================*/
  410. BOOL CAdoRecordSet::CancelUpdate()
  411. {
  412. ASSERT(m_pRecordset != NULL);
  413. try
  414. {
  415. if (m_pRecordset != NULL) 
  416. {
  417. if (GetEditMode() == adEditNone || m_pRecordset->CancelUpdate() == S_OK)
  418. {
  419. return TRUE;
  420. }
  421. }
  422. }
  423. catch (_com_error e)
  424. {
  425. TRACE(_T("Warning: CancelUpdate 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  426. return FALSE;
  427. return FALSE;
  428. }
  429. /*========================================================================
  430. Name: 取消挂起的批更新.
  431. -----------------------------------------------------
  432. Params: AffectRecords   可选的 AffectEnum 值, 决定CancelBatch 方法
  433. 所影响记录的数目, 可为下列常量之一: 
  434. [常量] [说明] 
  435. -------------------------------------------------
  436. AdAffectCurrent 仅取消当前记录的挂起更新. 
  437. AdAffectGroup 对满足当前 Filter 属性设置的记录取消挂起更新.
  438. 使用该选项时,必须将 Filter 属性设置为合法的预
  439. 定义常量之一. 
  440. AdAffectAll 默认值.取消 Recordset 对象中所有记录的挂起更
  441. 新,包括由当前 Filter 属性设置所隐藏的任何记录. 
  442. ==========================================================================*/
  443. BOOL CAdoRecordSet::CancelBatch(AffectEnum AffectRecords)
  444. {
  445. ASSERT(m_pRecordset != NULL);
  446. try
  447. {
  448. if (m_pRecordset != NULL) 
  449. {
  450. return (m_pRecordset->CancelBatch(AffectRecords) == S_OK);
  451. }
  452. }
  453. catch (_com_error e)
  454. {
  455. TRACE(_T("Warning: CancelBatch 发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  456. return FALSE;
  457. return FALSE;
  458. }
  459. /*========================================================================
  460. Params:  AffectRecords:  AffectEnum 值, 确定 Delete 方法所影响的记
  461. 录数目, 该值可以是下列常量之一.
  462. [常量] [说明 ]
  463. -------------------------------------------------
  464. AdAffectCurrent 默认. 仅删除当前记录. 
  465. AdAffectGroup 删除满足当前 Filter 属性设置的记录. 要使用该选
  466. 项, 必须将 Filter 属性设置为有效的预定义常量之一. 
  467. adAffectAll 删除所有记录. 
  468. adAffectAllChapters 删除所有子集记录. 
  469. ==========================================================================*/
  470. BOOL CAdoRecordSet::Delete(AffectEnum AffectRecords)
  471. {
  472. ASSERT(m_pRecordset != NULL);
  473. try
  474. {
  475. if (m_pRecordset != NULL) 
  476. {
  477. return (m_pRecordset->Delete(AffectRecords) == S_OK);
  478. }
  479. }
  480. catch (_com_error e)
  481. {
  482. TRACE(_T("Warning: Delete发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  483. return FALSE;
  484. return FALSE;
  485. }
  486. /*########################################################################
  487.   ------------------------------------------------
  488. 记录集导航操作
  489.   ------------------------------------------------
  490.   ########################################################################*/
  491. /*========================================================================
  492. Name: 将当前记录位置移动到 Recordse 中的第一个记录.
  493. ==========================================================================*/
  494. BOOL CAdoRecordSet::MoveFirst()
  495. {
  496. ASSERT(m_pRecordset != NULL);
  497. try
  498. {
  499. if (m_pRecordset != NULL) 
  500. {
  501. return SUCCEEDED(m_pRecordset->MoveFirst());
  502. }
  503. }
  504. catch (_com_error e)
  505. {
  506. TRACE(_T("Warning: MoveFirst 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  507. return FALSE;
  508. return FALSE;
  509. }
  510. /*========================================================================
  511. Name: 将当前记录位置移动到 Recordset 中的最后一个记录.
  512. -----------------------------------------------------
  513. Remarks: Recordset 对象必须支持书签或向后光标移动; 否则调用该方法将
  514. 产生错误.
  515. ==========================================================================*/
  516. BOOL CAdoRecordSet::MoveLast()
  517. {
  518. ASSERT(m_pRecordset != NULL);
  519. try
  520. {
  521. if (m_pRecordset != NULL) 
  522. {
  523. return SUCCEEDED(m_pRecordset->MoveLast());
  524. }
  525. }
  526. catch (_com_error e)
  527. {
  528. TRACE(_T("Warning: MoveLast 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  529. return FALSE;
  530. return FALSE;
  531. }
  532. /*========================================================================
  533. Name: 将当前记录位置向后移动一个记录(向记录集的顶部).
  534. -----------------------------------------------------
  535. Remarks: Recordset 对象必须支持书签或向后游标移动; 否则方法调用将产
  536. 生错误.如果首记录是当前记录并且调用 MovePrevious 方法, 则 ADO 将当前记
  537. 录设置在 Recordset (BOF为True) 的首记录之前. 而BOF属性为 True 时向后移
  538. 动将产生错误. 如果 Recordse 对象不支持书签或向后游标移动, 则 MovePrevious 
  539. 方法将产生错误.
  540. ==========================================================================*/
  541. BOOL CAdoRecordSet::MovePrevious()
  542. {
  543. ASSERT(m_pRecordset != NULL);
  544. try
  545. {
  546. if (m_pRecordset != NULL) 
  547. {
  548. return SUCCEEDED(m_pRecordset->MovePrevious());
  549. }
  550. }
  551. catch (_com_error e)
  552. {
  553. TRACE(_T("Warning: MovePrevious 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  554. return FALSE;
  555. }
  556. return FALSE;
  557. }
  558. /*========================================================================
  559. Name: 将当前记录向前移动一个记录(向 Recordset 的底部).
  560. -----------------------------------------------------
  561. Remarks: 如果最后一个记录是当前记录并且调用 MoveNext 方法, 则 ADO 将
  562. 当前记录设置到 Recordset (EOF为 True)的尾记录之后. 当 EOF 属性已经为 
  563. True 时试图向前移动将产生错误.
  564. ==========================================================================*/
  565. BOOL CAdoRecordSet::MoveNext()
  566. {
  567. ASSERT(m_pRecordset != NULL);
  568. try
  569. {
  570. if (m_pRecordset != NULL) 
  571. {
  572. return SUCCEEDED(m_pRecordset->MoveNext());
  573. }
  574. }
  575. catch (_com_error e)
  576. {
  577. TRACE(_T("Warning: MoveNext 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  578. return FALSE;
  579. }
  580. return FALSE;
  581. }
  582. /*========================================================================
  583. Name: 移动 Recordset 对象中当前记录的位置.
  584.     ----------------------------------------------------------
  585. Params:
  586. - lRecords    带符号长整型表达式, 指定当前记录位置移动的记录数.
  587. - Start    可选, 字符串或变体型, 用于计算书签. 也可为下列 
  588. BookmarkEnum 值之一: 
  589. [常量] [说明] 
  590. --------------------------------
  591. adBookmarkCurrent 默认. 从当前记录开始. 
  592. adBookmarkFirst 从首记录开始. 
  593. adBookmarkLast 从尾记录开始. 
  594. ==========================================================================*/
  595. BOOL CAdoRecordSet::Move(long lRecords, _variant_t Start)
  596. {
  597. ASSERT(m_pRecordset != NULL);
  598. try
  599. {
  600. if (m_pRecordset != NULL) 
  601. {
  602. return SUCCEEDED(m_pRecordset->Move(lRecords, _variant_t(Start)));
  603. }
  604. }
  605. catch (_com_error e)
  606. {
  607. TRACE(_T("Warning: Move 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  608. return FALSE;
  609. return FALSE;
  610. }
  611. /*########################################################################
  612.   ------------------------------------------------
  613.   记录集属性
  614.   ------------------------------------------------
  615.   ########################################################################*/
  616. /*========================================================================
  617. Name: 取得记录集对象的状态(是打开状态还是关闭状态). 对异步方式执
  618. 行的 Recordset 对象, 则说明当前的对象状态是连接、执行还是获取状态.
  619. -----------------------------------------------------
  620. returns: 返回下列常量之一的长整型值.
  621. [常量] [说明] 
  622. ----------------------------------
  623. adStateClosed 指示对象是关闭的. 
  624. adStateOpen 指示对象是打开的. 
  625. adStateConnecting 指示 Recordset 对象正在连接. 
  626. adStateExecuting 指示 Recordset 对象正在执行命令. 
  627. adStateFetching 指示 Recordset 对象的行正在被读取. 
  628. -----------------------------------------------------
  629. Remarks:  可以随时使用 State 属性确定指定对象的当前状态. 该属性是只
  630. 读的. Recordset 对象的 State 属性可以是组合值. 例如: 如果正在执行语句,
  631. 该属性将是 adStateOpen 和 adStateExecuting 的组合值.
  632. ==========================================================================*/
  633. long CAdoRecordSet::GetState()
  634. {
  635. ASSERT(m_pRecordset != NULL);
  636. try
  637. {
  638. return m_pRecordset->GetState();
  639. }
  640. catch (_com_error e)
  641. {
  642. TRACE(_T("Warning: GetState 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  643. return -1;
  644. return -1;
  645. }
  646. BOOL CAdoRecordSet::IsOpen()
  647. {
  648. try
  649. {
  650. return (m_pRecordset != NULL && (GetState() & adStateOpen));
  651. }
  652. catch (_com_error e)
  653. {
  654. TRACE(_T("Warning: IsOpen方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  655. return FALSE;
  656. return FALSE;
  657. }
  658. /*========================================================================
  659. Name: 指示有关批更新或其他大量操作的当前记录的状态.
  660. -----------------------------------------------------
  661. returns: 返回下列一个或多个 RecordStatusEnum 值之和.
  662. [常量] [说明]
  663. -------------------------------------------------
  664. adRecOK 成功地更新记录. 
  665. adRecNew 记录是新建的. 
  666. adRecModified 记录被修改. 
  667. adRecDeleted 记录被删除. 
  668. adRecUnmodified 记录没有修改. 
  669. adRecInvalid 由于书签无效, 记录没有保存. 
  670. adRecMultipleChanges 由于影响多个记录, 因此记录未被保存. 
  671. adRecPendingChanges 由于记录引用挂起的插入, 因此未被保存. 
  672. adRecCanceled 由于操作被取消, 未保存记录. 
  673. adRecCantRelease 由于现有记录锁定, 没有保存新记录. 
  674. adRecConcurrencyViolation 由于开放式并发在使用中, 记录未被保存. 
  675. adRecIntegrityViolation 由于用户违反完整性约束, 记录未被保存. 
  676. adRecMaxChangesExceeded 由于存在过多挂起更改, 记录未被保存. 
  677. adRecObjectOpen 由于与打开的储存对象冲突, 记录未被保存. 
  678. adRecOutOfMemory 由于计算机内存不足, 记录未被保存. 
  679. adRecPermissionDenied 由于用户没有足够的权限, 记录未被保存. 
  680. adRecSchemaViolation 由于记录违反基本数据库的结构, 因此未被保存. 
  681. adRecDBDeleted 记录已经从数据源中删除. 
  682. -----------------------------------------------------
  683. Remarks: 使用 Status 属性查看在批更新中被修改的记录有哪些更改被挂起.
  684. 也可使用 Status 属性查看大量操作时失败记录的状态. 例如, 调用 Recordset
  685. 对象的 Resync、UpdateBatch 或 CancelBatch 方法, 或者设置 Recordset 对象
  686. 的 Filter 属性为书签数组. 使用该属性, 可检查指定记录为何失败并将问题解
  687. 决.
  688. ==========================================================================*/
  689. long CAdoRecordSet::GetStatus()
  690. {
  691. ASSERT(m_pRecordset != NULL);
  692. try
  693. {
  694. return m_pRecordset->GetStatus();
  695. }
  696. catch (_com_error e)
  697. {
  698. TRACE(_T("Warning: GetStatus 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  699. return -1;
  700. return -1;
  701. }
  702. /*========================================================================
  703. Name: 获取当前记录集中记录数目
  704. ==========================================================================*/
  705. long CAdoRecordSet::GetRecordCount()
  706. {
  707. ASSERT(m_pRecordset != NULL);
  708. try
  709. {
  710. long count = m_pRecordset->GetRecordCount();
  711. // 如果ado不支持此属性,则手工计算记录数目 --------
  712. if (count < 0)
  713. {
  714. long pos = GetAbsolutePosition();
  715. MoveFirst();
  716. count = 0;
  717. while (!IsEOF()) 
  718. {
  719. count++;
  720. MoveNext();
  721. }
  722. SetAbsolutePosition(pos);
  723. }
  724. return count;
  725. }
  726. catch (_com_error e)
  727. {
  728. TRACE(_T("Warning: GetRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  729. return -1;
  730. }
  731. /*========================================================================
  732. Name: 获取当前记录集中字段数目
  733. ==========================================================================*/
  734. long CAdoRecordSet::GetFieldsCount()
  735. {
  736. ASSERT(m_pRecordset != NULL);
  737. try
  738. {
  739. return GetFields()->Count;
  740. }
  741. catch(_com_error e)
  742. {
  743. TRACE(_T("Warning: GetFieldsCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  744. return -1;
  745. }
  746. /*========================================================================
  747. Name: 指示通过查询返回 Recordset 的记录的最大数目. 
  748. ==========================================================================*/
  749. long CAdoRecordSet::GetMaxRecordCount()
  750. {
  751. ASSERT(m_pRecordset != NULL);
  752. try
  753. {
  754. return m_pRecordset->GetMaxRecords();
  755. }
  756. catch (_com_error e)
  757. {
  758. TRACE(_T("Warning: GetMaxRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  759. return -1;
  760. }
  761. }
  762. BOOL CAdoRecordSet::SetMaxRecordCount(long count)
  763. {
  764. ASSERT(m_pRecordset != NULL);
  765. try
  766. {
  767. m_pRecordset->PutMaxRecords(count);
  768. return TRUE;
  769. }
  770. catch (_com_error e)
  771. {
  772. TRACE(_T("Warning: GetMaxRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  773. return FALSE;
  774. }
  775. }
  776. /*========================================================================
  777. Name: 指针是否在在记录集头
  778. ==========================================================================*/
  779. BOOL CAdoRecordSet::IsBOF()
  780. {
  781. ASSERT(m_pRecordset != NULL);
  782. try
  783. {
  784. return m_pRecordset->adoBOF;
  785. }
  786. catch(_com_error e)
  787. {
  788. TRACE(_T("Warning: IsBOF 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  789. return FALSE;
  790. return FALSE;
  791. }
  792. /*========================================================================
  793. Name: 指针是否在在记录集尾
  794. ==========================================================================*/
  795. BOOL CAdoRecordSet::IsEOF()
  796. {
  797. ASSERT(m_pRecordset != NULL);
  798. try
  799. {
  800. return m_pRecordset->adoEOF;
  801. }
  802. catch (_com_error e)
  803. {
  804. TRACE(_T("Warning: IsEOF 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  805. return FALSE;
  806. }
  807. }
  808. EditModeEnum CAdoRecordSet::GetEditMode()
  809. {
  810. ASSERT(m_pRecordset != NULL);
  811. try
  812. {
  813. if (m_pRecordset != NULL) 
  814. {
  815. return m_pRecordset->GetEditMode();
  816. }
  817. }
  818. catch (_com_error e)
  819. {
  820. TRACE(_T("Warning: UpdateBatch 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  821. return adEditNone;
  822. return adEditNone; 
  823. }
  824. long CAdoRecordSet::GetPageCount()
  825. {
  826. ASSERT(m_pRecordset != NULL);
  827. try
  828. {
  829. return m_pRecordset->GetPageCount();
  830. }
  831. catch (_com_error &e)
  832. {
  833. TRACE(_T("Warning: GetPageCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  834. return -1;
  835. }
  836. }
  837. BOOL CAdoRecordSet::SetCacheSize(const long &lCacheSize)
  838. {
  839. ASSERT(m_pRecordset != NULL);
  840. try
  841. {
  842. if (m_pRecordset != NULL && !(GetState() & adStateExecuting))
  843. {
  844. m_pRecordset->PutCacheSize(lCacheSize);
  845. }
  846. }
  847. catch (const _com_error& e)
  848. {
  849. TRACE(_T("Warning: SetCacheSize方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  850. return FALSE;
  851. }
  852. return TRUE;
  853. }
  854. long CAdoRecordSet::GetPageSize()
  855. {
  856. ASSERT(m_pRecordset != NULL);
  857. try
  858. {
  859. return m_pRecordset->GetPageSize();
  860. }
  861. catch (_com_error &e)
  862. {
  863. TRACE(_T("Warning: GetPageCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  864. return -1;
  865. }
  866. }
  867. /*========================================================================
  868. name: 指定当前记录所在的页.
  869.     ----------------------------------------------------------
  870. returns: 置或返回从 1 到 Recordset 对象 (PageCount) 所含页数的长整型
  871. 值,或者返回以下常量. 
  872. [常量] [说明]
  873. ---------------------------------
  874. adPosUnknown Recordset 为空,当前位置未知,或者提供者不支持 AbsolutePage 属性.  
  875. adPosBOF 当前记录指针位于 BOF(即 BOF 属性为 True).  
  876. adPosEOF 当前记录指针位于 EOF(即 EOF 属性为 True).  
  877. ==========================================================================*/
  878. BOOL CAdoRecordSet::SetAbsolutePage(int nPage)
  879. {
  880. ASSERT(m_pRecordset != NULL);
  881. try
  882. {
  883. m_pRecordset->PutAbsolutePage((enum PositionEnum)nPage);
  884. return TRUE;
  885. }
  886. catch(_com_error &e)
  887. {
  888. TRACE(_T("Warning: SetAbsolutePage 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  889. return FALSE;
  890. }
  891. }
  892. long CAdoRecordSet::GetAbsolutePage()
  893. {
  894. ASSERT(m_pRecordset != NULL);
  895. try
  896. {
  897. return m_pRecordset->GetAbsolutePage();
  898. }
  899. catch(_com_error &e)
  900. {
  901. TRACE(_T("Warning: GetAbsolutePage 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  902. return -1;
  903. }
  904. }
  905. /*========================================================================
  906. name: 指定 Recordset 对象当前记录的序号位置. 
  907.     ----------------------------------------------------------
  908. returns: 设置或返回从 1 到 Recordset 对象 (PageCount) 所含页数的长整
  909. 型值,或者返回以下常量. 
  910. [常量] [说明]
  911. ---------------------------------
  912. adPosUnknown Recordset 为空,当前位置未知,或者提供者不支持 AbsolutePage 属性.  
  913. adPosBOF 当前记录指针位于 BOF(即 BOF 属性为 True).  
  914. adPosEOF 当前记录指针位于 EOF(即 EOF 属性为 True).  
  915.     ----------------------------------------------------------
  916. Remarks: 使用 AbsolutePosition 属性可根据其在 Recordset 中的序号
  917. 位置移动到记录,或确定当前记录的序号位置. 提供者必须支持该属性的相应功
  918. 能才能使用该属性. 
  919. 同 AbsolutePage 属性一样,AbsolutePosition 从 1 开始,并在当前记录
  920. 为 Recordset 中的第一个记录时等于 1. 从 RecordCount 属性可获得 Recordset 
  921. 对象的总记录数. 
  922. 设置 AbsolutePosition 属性时,即使该属性指向位于当前缓存中的记录,
  923. ADO 也将使用以指定的记录开始的新记录组重新加载缓存. CacheSize 属性决定
  924. 该记录组的大小. 
  925. 注意   不能将 AbsolutePosition 属性作为替代的记录编号使用. 删除前面
  926. 的记录时,给定记录的当前位置将发生改变. 如果 Recordset 对象被重新查询或
  927. 重新打开,则无法保证给定记录有相同的 AbsolutePosition. 书签仍然是保持和
  928. 返回给定位置的推荐方式,并且在所有类型的 Recordset 对象的定位时是唯一的
  929. 方式. 
  930. ==========================================================================*/
  931. BOOL CAdoRecordSet::SetAbsolutePosition(int nPosition)
  932. {
  933. ASSERT(m_pRecordset != NULL);
  934. try
  935. {
  936. m_pRecordset->PutAbsolutePosition((enum PositionEnum)nPosition);
  937. return TRUE;
  938. }
  939. catch(_com_error &e)
  940. {
  941. TRACE(_T("Warning: SetAbsolutePosition 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  942. return FALSE;
  943. }
  944. }
  945. long CAdoRecordSet::GetAbsolutePosition()
  946. {
  947. ASSERT(m_pRecordset != NULL);
  948. try
  949. {
  950. return m_pRecordset->GetAbsolutePosition();
  951. }
  952. catch(_com_error &e)
  953. {
  954. TRACE(_T("Warning: GetAbsolutePosition 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  955. return -1;
  956. }
  957. }
  958. BOOL CAdoRecordSet::SetCursorLocation(CursorLocationEnum CursorLocation)
  959. {
  960. ASSERT(m_pRecordset != NULL);
  961. try
  962. {
  963. m_pRecordset->PutCursorLocation(CursorLocation);
  964. return TRUE;
  965. }
  966. catch (_com_error e)
  967. {
  968. TRACE(_T("Warning: PutCursorLocation 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  969. return FALSE;
  970. }
  971. }
  972. CursorLocationEnum CAdoRecordSet::GetCursorLocation()
  973. {
  974. ASSERT(m_pRecordset != NULL);
  975. try
  976. {
  977. return m_pRecordset->GetCursorLocation();
  978. }
  979. catch (_com_error e)
  980. {
  981. TRACE(_T("Warning: GetCursorLocation 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  982. return adUseNone;
  983. }
  984. }
  985. BOOL CAdoRecordSet::SetCursorType(CursorTypeEnum CursorType)
  986. {
  987. ASSERT(m_pRecordset != NULL);
  988. try
  989. {
  990. m_pRecordset->PutCursorType(CursorType);
  991. return TRUE;
  992. }
  993. catch (_com_error e)
  994. {
  995. TRACE(_T("Warning: SetCursorType 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  996. return FALSE;
  997. }
  998. }
  999. CursorTypeEnum CAdoRecordSet::GetCursorType()
  1000. {
  1001. ASSERT(m_pRecordset != NULL);
  1002. try
  1003. {
  1004. return m_pRecordset->GetCursorType();
  1005. }
  1006. catch (_com_error e)
  1007. {
  1008. TRACE(_T("Warning: GetCursorType 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1009. return adOpenUnspecified;
  1010. }
  1011. }
  1012. /*========================================================================
  1013. Remarks: Recordset 对象包括 Field 对象组成的 Fields 集合. 每个Field
  1014.  对象对应 Recordset 集中的一列.
  1015. ==========================================================================*/
  1016. FieldsPtr CAdoRecordSet::GetFields()
  1017. {
  1018. ASSERT(m_pRecordset != NULL);
  1019. try
  1020. {
  1021. return m_pRecordset->GetFields();
  1022. }
  1023. catch (_com_error e)
  1024. {
  1025. TRACE(_T("Warning: GetFields 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1026. return NULL;
  1027. return NULL;
  1028. }
  1029. /*========================================================================
  1030. Remarks: 取得指定列字段的字段名.
  1031. ==========================================================================*/
  1032. CString CAdoRecordSet::GetFieldName(long lIndex)
  1033. {
  1034. ASSERT(m_pRecordset != NULL);
  1035. CString strFieldName;
  1036. try
  1037. {
  1038. strFieldName = LPCTSTR(m_pRecordset->Fields->GetItem(_variant_t(lIndex))->GetName());
  1039. }
  1040. catch (_com_error e)
  1041. {
  1042. TRACE(_T("Warning: GetFieldName 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1043. }
  1044. return strFieldName;
  1045. }
  1046. /*========================================================================
  1047. name: 取得 Field 对象一项或多项属性.
  1048.     ----------------------------------------------------------
  1049. returns: 对于 Field 对象, Attributes 属性为只读, 其值可能为以下任意
  1050. 一个或多个 FieldAttributeEnum 值的和.
  1051.   [常量] [说明] 
  1052.   -------------------------------------------
  1053.   adFldMayDefer 指示字段被延迟, 即不从拥有整个记录的数据源检索
  1054. 字段值, 仅在显式访问这些字段时才进行检索. 
  1055.   adFldUpdatable 指示可以写入该字段. 
  1056.   adFldUnknownUpdatable 指示提供者无法确定是否可以写入该字段. 
  1057.   adFldFixed 指示该字段包含定长数据. 
  1058.   adFldIsNullable 指示该字段接受 Null 值. 
  1059.   adFldMayBeNull 指示可以从该字段读取 Null 值. 
  1060.   adFldLong 指示该字段为长二进制字段. 并指示可以使用 AppendChunk 
  1061. 和 GetChunk 方法. 
  1062.   adFldRowID 指示字段包含持久的行标识符, 该标识符无法被写入
  1063. 并且除了对行进行标识(如记录号、唯一标识符等)外不
  1064. 存在有意义的值. 
  1065.   adFldRowVersion 指示该字段包含用来跟踪更新的某种时间或日期标记. 
  1066.   adFldCacheDeferred 指示提供者缓存了字段值, 并已完成随后对缓存的读取. 
  1067. ==========================================================================*/
  1068. long CAdoRecordSet::GetFieldAttributes(long lIndex)
  1069. {
  1070. ASSERT(m_pRecordset != NULL);
  1071. try
  1072. {
  1073. return m_pRecordset->Fields->GetItem(_variant_t(lIndex))->GetAttributes();
  1074. }
  1075. catch (_com_error e)
  1076. {
  1077. TRACE(_T("Warning: GetFieldAttributes 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1078. return -1;
  1079. }
  1080. }
  1081. long CAdoRecordSet::GetFieldAttributes(LPCTSTR lpszFieldName)
  1082. {
  1083. ASSERT(m_pRecordset != NULL);
  1084. try
  1085. {
  1086. return m_pRecordset->Fields->GetItem(_variant_t(lpszFieldName))->GetAttributes();
  1087. }
  1088. catch (_com_error e)
  1089. {
  1090. TRACE(_T("Warning: GetFieldAttributes 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1091. return -1;
  1092. }
  1093. }
  1094. /*========================================================================
  1095. Name: 指示 Field 对象所定义的长度.
  1096.     ----------------------------------------------------------
  1097. returns: 返回某个字段定义的长度(按字节数)的长整型值.
  1098.     ----------------------------------------------------------
  1099. Remarks: 使用 DefinedSize 属性可确定 Field 对象的数据容量.
  1100. ==========================================================================*/
  1101. long CAdoRecordSet::GetFieldDefineSize(long lIndex)
  1102. {
  1103. ASSERT(m_pRecordset != NULL);
  1104. try
  1105. {
  1106. return m_pRecordset->Fields->GetItem(_variant_t(lIndex))->DefinedSize;
  1107. }
  1108. catch (_com_error e)
  1109. {
  1110. TRACE(_T("Warning: GetDefineSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1111. return -1;
  1112. }
  1113. }
  1114. long CAdoRecordSet::GetFieldDefineSize(LPCTSTR lpszFieldName)
  1115. {
  1116. ASSERT(m_pRecordset != NULL);
  1117. try
  1118. {
  1119. return m_pRecordset->Fields->GetItem(_variant_t(lpszFieldName))->DefinedSize;
  1120. }
  1121. catch (_com_error e)
  1122. {
  1123. TRACE(_T("Warning: GetDefineSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1124. return -1;
  1125. }
  1126. }
  1127. /*========================================================================
  1128. Name: 取得字段的值的实际长度.
  1129.     ----------------------------------------------------------
  1130. returns: 返回长整型值.某些提供者允许设置该属性以便为 BLOB 数据预留
  1131. 空间, 在此情况下默认值为 0.
  1132.     ----------------------------------------------------------
  1133. Remarks: 使用 ActualSize 属性可返回 Field 对象值的实际长度.对于所有
  1134. 字段,ActualSize 属性为只读.如果 ADO 无法确定 Field 对象值的实
  1135. 际长度, ActualSize 属性将返回 adUnknown.
  1136. 如以下范例所示, ActualSize 和  DefinedSize 属性有所不同: 
  1137. adVarChar 声明类型且最大长度为 50 个字符的 Field 对象将返回为 
  1138. 50 的 DefinedSize 属性值, 但是返回的 ActualSize 属性值是当前记
  1139. 录的字段中存储的数据的长度.
  1140. ==========================================================================*/
  1141. long CAdoRecordSet::GetFieldActualSize(long lIndex)
  1142. {
  1143. ASSERT(m_pRecordset != NULL);
  1144. try
  1145. {
  1146. return m_pRecordset->Fields->GetItem(_variant_t(lIndex))->ActualSize;
  1147. }
  1148. catch (_com_error e)
  1149. {
  1150. TRACE(_T("Warning: GetFieldActualSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1151. return -1;
  1152. }
  1153. }
  1154. long CAdoRecordSet::GetFieldActualSize(LPCTSTR lpszFieldName)
  1155. {
  1156. ASSERT(m_pRecordset != NULL);
  1157. try
  1158. {
  1159. return m_pRecordset->Fields->GetItem(_variant_t(lpszFieldName))->ActualSize;
  1160. }
  1161. catch (_com_error e)
  1162. {
  1163. TRACE(_T("Warning: GetFieldActualSize 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1164. return -1;
  1165. }
  1166. }
  1167. /*========================================================================
  1168. returns: 返回下列值之一. 相应的 OLE DB 类型标识符在下表的说明栏的括
  1169. 号中给出.
  1170.   [常量] [说明] 
  1171.   ---------------------------------------------------------
  1172.   adArray 与其他类型一起加入逻辑 OR 以指示该数据是那种类型的
  1173. 安全数组 (DBTYPE_ARRAY). 
  1174.   adBigInt 8 字节带符号的整数 (DBTYPE_I8). 
  1175.   adBinary 二进制值 (DBTYPE_BYTES). 
  1176.   adBoolean 布尔型值 (DBTYPE_BOOL). 
  1177.   adByRef 与其他类型一起加入逻辑 OR 以指示该数据是其他类型数
  1178. 据的指针 (DBTYPE_BYREF). 
  1179.   adBSTR 以空结尾的字符串 (Unicode) (DBTYPE_BSTR). 
  1180.   adChar 字符串值 (DBTYPE_STR). 
  1181.   adCurrency 货币值 (DBTYPE_CY).货币数字的小数点位置固定、小数
  1182. 点右侧有四位数字.该值保存为 8 字节范围为10,000 的带符
  1183. 号整型值. 
  1184.   adDate 日期值 (DBTYPE_DATE).日期按双精度型数值来保存, 数
  1185. 字全部表示从 1899 年 12 月 30 开始的日期数.小数部分是
  1186. 一天当中的片段时间. 
  1187.   adDBDate 日期值 (yyyymmdd) (DBTYPE_DBDATE). 
  1188.   adDBTime 时间值 (hhmmss) (DBTYPE_DBTIME). 
  1189.   adDBTimeStamp 时间戳 (yyyymmddhhmmss 加 10 亿分之一的小数)(DBTYPE_DBTIMESTAMP). 
  1190.   adDecimal 具有固定精度和范围的精确数字值 (DBTYPE_DECIMAL). 
  1191.   adDouble 双精度浮点值 (DBTYPE_R8). 
  1192.   adEmpty 未指定值 (DBTYPE_EMPTY). 
  1193.   adError 32 - 位错误代码 (DBTYPE_ERROR). 
  1194.   adGUID 全局唯一的标识符 (GUID) (DBTYPE_GUID). 
  1195.   adIDispatch OLE 对象上 Idispatch 接口的指针 (DBTYPE_IDISPATCH). 
  1196.   adInteger 4 字节的带符号整型 (DBTYPE_I4). 
  1197.   adIUnknown OLE 对象上 IUnknown 接口的指针 (DBTYPE_IUNKNOWN).
  1198.   adLongVarBinary 长二进制值. 
  1199.   adLongVarChar 长字符串值. 
  1200.   adLongVarWChar 以空结尾的长字符串值. 
  1201.   adNumeric 具有固定精度和范围的精确数字值 (DBTYPE_NUMERIC). 
  1202.   adSingle 单精度浮点值 (DBTYPE_R4). 
  1203.   adSmallInt 2 字节带符号整型 (DBTYPE_I2). 
  1204.   adTinyInt 1 字节带符号整型 (DBTYPE_I1). 
  1205.   adUnsignedBigInt 8 字节不带符号整型 (DBTYPE_UI8). 
  1206.   adUnsignedInt 4 字节不带符号整型 (DBTYPE_UI4). 
  1207.   adUnsignedSmallInt 2 字节不带符号整型 (DBTYPE_UI2). 
  1208.   adUnsignedTinyInt 1 字节不带符号整型 (DBTYPE_UI1). 
  1209.   adUserDefined 用户定义的变量 (DBTYPE_UDT). 
  1210.   adVarBinary 二进制值. 
  1211.   adVarChar 字符串值. 
  1212.   adVariant 自动变体型 (DBTYPE_VARIANT). 
  1213.   adVector 与其他类型一起加入逻辑 OR 中, 指示数据是 DBVECTOR 
  1214. 结构(由 OLE DB 定义).该结构含有元素的计数和其他类型 
  1215. (DBTYPE_VECTOR) 数据的指针. 
  1216.   adVarWChar 以空结尾的 Unicode 字符串. 
  1217.   adWChar 以空结尾的 Unicode 字符串 (DBTYPE_WSTR). 
  1218.     ----------------------------------------------------------
  1219. Remarks: 返回指定字段的数据类型.
  1220. ==========================================================================*/
  1221. DataTypeEnum CAdoRecordSet::GetFieldType(long lIndex)
  1222. {
  1223. ASSERT(m_pRecordset != NULL);
  1224. try 
  1225. {
  1226. return m_pRecordset->Fields->GetItem(_variant_t(lIndex))->GetType();
  1227. }
  1228. catch (_com_error e)
  1229. {
  1230. TRACE(_T("Warning: GetField 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1231. return adEmpty;
  1232. }
  1233. }
  1234. DataTypeEnum CAdoRecordSet::GetFieldType(LPCTSTR lpszFieldName)
  1235. {
  1236. ASSERT(m_pRecordset != NULL);
  1237. try 
  1238. {
  1239. return m_pRecordset->Fields->GetItem(_variant_t(lpszFieldName))->GetType();
  1240. }
  1241. catch (_com_error e)
  1242. {
  1243. TRACE(_T("Warning: GetField发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1244. return adEmpty;
  1245. }
  1246. }
  1247. BOOL CAdoRecordSet::IsFieldNull(LPCTSTR lpFieldName)
  1248. {
  1249. try
  1250. {
  1251. _variant_t vt = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
  1252. return (vt.vt == VT_NULL);
  1253. }
  1254. catch (_com_error e)
  1255. {
  1256. TRACE(_T("Warning: IsFieldNull 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1257. return FALSE;
  1258. }
  1259. }
  1260. BOOL CAdoRecordSet::IsFieldNull(long index)
  1261. {
  1262. try
  1263. {
  1264. _variant_t vt = m_pRecordset->Fields->GetItem(_variant_t(index))->Value;
  1265. return (vt.vt == VT_NULL);
  1266. }
  1267. catch (_com_error e)
  1268. {
  1269. TRACE(_T("Warning: IsFieldNull 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1270. return FALSE;
  1271. }
  1272. }
  1273. /*========================================================================
  1274. Name: 取得指定列的字段对象的指针.
  1275. ==========================================================================*/
  1276. FieldPtr CAdoRecordSet::GetField(long lIndex)
  1277. {
  1278. try
  1279. {
  1280. return GetFields()->GetItem(_variant_t(lIndex));
  1281. }
  1282. catch (_com_error e)
  1283. {
  1284. TRACE(_T("Warning: GetField发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1285. return NULL;
  1286. }
  1287. }
  1288. FieldPtr CAdoRecordSet::GetField(LPCTSTR lpszFieldName)
  1289. {
  1290. try
  1291. {
  1292. return GetFields()->GetItem(_variant_t(lpszFieldName));
  1293. }
  1294. catch (_com_error e)
  1295. {
  1296. TRACE(_T("Warning: GetField发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1297. return NULL;
  1298. }
  1299. }
  1300. /*########################################################################
  1301.   ------------------------------------------------
  1302.   设置字段的值
  1303.   ------------------------------------------------
  1304.   ########################################################################*/
  1305. BOOL CAdoRecordSet::PutCollect(long index, const _variant_t &value)
  1306. {
  1307. ASSERT(m_pRecordset != NULL);
  1308. ASSERT(index < GetFieldsCount());
  1309. try
  1310. {
  1311. if (m_pRecordset != NULL) 
  1312. {
  1313. m_pRecordset->PutCollect(_variant_t(index), value);
  1314. return TRUE;
  1315. }
  1316. }
  1317. catch (_com_error e)
  1318. {
  1319. TRACE(_T("Warning: PutCollect 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1320. return FALSE;
  1321. return FALSE;
  1322. }
  1323. BOOL CAdoRecordSet::PutCollect(LPCSTR strFieldName, const _variant_t &value)
  1324. {
  1325. ASSERT(m_pRecordset != NULL);
  1326. try
  1327. {
  1328. if (m_pRecordset != NULL) 
  1329. {
  1330. m_pRecordset->put_Collect(_variant_t(strFieldName), value);
  1331. return TRUE;
  1332. }
  1333. }
  1334. catch (_com_error e)
  1335. {
  1336. return FALSE;
  1337. TRACE(_T("Warning: PutCollect 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1338. return FALSE;
  1339. }
  1340. BOOL CAdoRecordSet::PutCollect(long index, const bool &value)
  1341. {
  1342. ASSERT(m_pRecordset != NULL);
  1343. #ifdef _DEBUG
  1344. if (GetFieldType(index) != adBoolean)
  1345. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1346. #endif
  1347. return PutCollect(index, _variant_t(value));
  1348. }
  1349. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const bool &value)
  1350. {
  1351. ASSERT(m_pRecordset != NULL);
  1352. #ifdef _DEBUG
  1353. if (GetFieldType(strFieldName) != adBoolean)
  1354. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1355. #endif
  1356. return PutCollect(strFieldName, _variant_t(value));
  1357. }
  1358. BOOL CAdoRecordSet::PutCollect(long index, const BYTE &value)
  1359. {
  1360. ASSERT(m_pRecordset != NULL);
  1361. #ifdef _DEBUG
  1362. if (GetFieldType(index) != adUnsignedTinyInt)
  1363. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1364. #endif
  1365. return PutCollect(index, _variant_t(value));
  1366. }
  1367. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const BYTE &value)
  1368. {
  1369. ASSERT(m_pRecordset != NULL);
  1370. #ifdef _DEBUG
  1371. if (GetFieldType(strFieldName) != adUnsignedTinyInt)
  1372. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1373. #endif
  1374. return PutCollect(strFieldName, _variant_t(value));
  1375. }
  1376. BOOL CAdoRecordSet::PutCollect(long index, const short &value)
  1377. {
  1378. ASSERT(m_pRecordset != NULL);
  1379. #ifdef _DEBUG
  1380. if (GetFieldType(index) != adSmallInt)
  1381. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1382. #endif
  1383. return PutCollect(index, _variant_t(value));
  1384. }
  1385. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const short &value)
  1386. {
  1387. ASSERT(m_pRecordset != NULL);
  1388. #ifdef _DEBUG
  1389. if (GetFieldType(strFieldName) != adSmallInt)
  1390. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1391. #endif
  1392. return PutCollect(strFieldName, _variant_t(value));
  1393. }
  1394. BOOL CAdoRecordSet::PutCollect(long index, const int &value)
  1395. {
  1396. ASSERT(m_pRecordset != NULL);
  1397. #ifdef _DEBUG
  1398. if (GetFieldType(index) != adInteger)
  1399. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1400. #endif
  1401. return PutCollect(index, _variant_t(long(value)));
  1402. }
  1403. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const int &value)
  1404. {
  1405. ASSERT(m_pRecordset != NULL);
  1406. #ifdef _DEBUG
  1407. if (GetFieldType(strFieldName) != adInteger)
  1408. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1409. #endif
  1410. return PutCollect(strFieldName, _variant_t(long(value)));
  1411. }
  1412. BOOL CAdoRecordSet::PutCollect(long index, const long &value)
  1413. {
  1414. ASSERT(m_pRecordset != NULL);
  1415. #ifdef _DEBUG
  1416. if (GetFieldType(index) != adBigInt)
  1417. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1418. #endif
  1419. return PutCollect(index, _variant_t(value));
  1420. }
  1421. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const long &value)
  1422. {
  1423. ASSERT(m_pRecordset != NULL);
  1424. #ifdef _DEBUG
  1425. if (GetFieldType(strFieldName) != adBigInt)
  1426. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1427. #endif
  1428. return PutCollect(strFieldName, _variant_t(value));
  1429. }
  1430. BOOL CAdoRecordSet::PutCollect(long index, const DWORD &value)
  1431. {
  1432. ASSERT(m_pRecordset != NULL);
  1433. #ifdef _DEBUG
  1434. if (GetFieldType(index) != adUnsignedBigInt)
  1435. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1436. #endif
  1437. _variant_t vt;
  1438. vt.vt = VT_UI4;
  1439. vt.ulVal = value;
  1440. return PutCollect(index, vt);
  1441. }
  1442. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const DWORD &value)
  1443. {
  1444. ASSERT(m_pRecordset != NULL);
  1445. #ifdef _DEBUG
  1446. if (GetFieldType(strFieldName) != adUnsignedBigInt)
  1447. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1448. #endif
  1449. _variant_t vt;
  1450. vt.vt = VT_UI4;
  1451. vt.ulVal = value;
  1452. return PutCollect(strFieldName, vt);
  1453. }
  1454. BOOL CAdoRecordSet::PutCollect(long index, const float &value)
  1455. {
  1456. ASSERT(m_pRecordset != NULL);
  1457. #ifdef _DEBUG
  1458. if (GetFieldType(index) != adSingle)
  1459. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1460. #endif
  1461. return PutCollect(index, _variant_t(value));
  1462. }
  1463. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const float &value)
  1464. {
  1465. ASSERT(m_pRecordset != NULL);
  1466. #ifdef _DEBUG
  1467. if (GetFieldType(strFieldName) != adSingle)
  1468. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1469. #endif
  1470. return PutCollect(strFieldName, _variant_t(value));
  1471. }
  1472. BOOL CAdoRecordSet::PutCollect(long index, const double &value)
  1473. {
  1474. ASSERT(m_pRecordset != NULL);
  1475. #ifdef _DEBUG
  1476. if (GetFieldType(index) != adDouble)
  1477. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1478. #endif
  1479. return PutCollect(index, _variant_t(value));
  1480. }
  1481. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const double &value)
  1482. {
  1483. ASSERT(m_pRecordset != NULL);
  1484. #ifdef _DEBUG
  1485. if (GetFieldType(strFieldName) != adDouble)
  1486. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1487. #endif
  1488. return PutCollect(strFieldName, _variant_t(value));
  1489. }
  1490. BOOL CAdoRecordSet::PutCollect(long index, const COleDateTime &value)
  1491. {
  1492. ASSERT(m_pRecordset != NULL);
  1493. #ifdef _DEBUG
  1494. if (   GetFieldType(index) != adDate
  1495. && GetFieldType(index) != adDBDate
  1496. && GetFieldType(index) != adDBTime
  1497. && GetFieldType(index) != adDBTimeStamp)
  1498. {
  1499. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1500. }
  1501. #endif
  1502. _variant_t vt;
  1503. vt.vt = VT_DATE;
  1504. vt.date = value;
  1505. return PutCollect(index, vt);
  1506. }
  1507. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const COleDateTime &value)
  1508. {
  1509. ASSERT(m_pRecordset != NULL);
  1510. #ifdef _DEBUG
  1511. if (   GetFieldType(strFieldName) != adDate
  1512. && GetFieldType(strFieldName) != adDBDate
  1513. && GetFieldType(strFieldName) != adDBTime
  1514. && GetFieldType(strFieldName) != adDBTimeStamp)
  1515. {
  1516. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1517. }
  1518. #endif
  1519. _variant_t vt;
  1520. vt.vt = VT_DATE;
  1521. vt.date = value;
  1522. return PutCollect(strFieldName, vt);
  1523. }
  1524. BOOL CAdoRecordSet::PutCollect(long index, const COleCurrency &value)
  1525. {
  1526. ASSERT(m_pRecordset != NULL);
  1527. #ifdef _DEBUG
  1528. if (GetFieldType(index) != adCurrency)
  1529. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1530. #endif
  1531. if (value.m_status == COleCurrency::invalid) return FALSE;
  1532. _variant_t vt;
  1533. vt.vt = VT_CY;
  1534. vt.cyVal = value.m_cur;
  1535. return PutCollect(index, vt);
  1536. }
  1537. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const COleCurrency &value)
  1538. {
  1539. ASSERT(m_pRecordset != NULL);
  1540. #ifdef _DEBUG
  1541. if (GetFieldType(strFieldName) != adCurrency)
  1542. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1543. #endif
  1544. if (value.m_status == COleCurrency::invalid) return FALSE;
  1545. _variant_t vt;
  1546. vt.vt = VT_CY;
  1547. vt.cyVal = value.m_cur;
  1548. return PutCollect(strFieldName, vt);
  1549. }
  1550. BOOL CAdoRecordSet::PutCollect(long index, const CString &value)
  1551. {
  1552. ASSERT(m_pRecordset != NULL);
  1553. #ifdef _DEBUG
  1554. if (! (GetFieldType(index) == adVarChar
  1555. || GetFieldType(index) == adChar
  1556. || GetFieldType(index) == adLongVarChar
  1557. || GetFieldType(index) == adVarWChar
  1558. || GetFieldType(index) == adWChar
  1559. || GetFieldType(index) == adLongVarWChar))
  1560. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1561. #endif
  1562. _variant_t vt;
  1563. vt.vt = value.IsEmpty() ? VT_NULL : VT_BSTR;
  1564. vt.bstrVal = value.AllocSysString();
  1565. return PutCollect(index, vt);
  1566. }
  1567. BOOL CAdoRecordSet::PutCollect(LPCTSTR strFieldName, const CString &value)
  1568. {
  1569. ASSERT(m_pRecordset != NULL);
  1570. #ifdef _DEBUG
  1571. if (! (GetFieldType(strFieldName) == adVarChar
  1572. || GetFieldType(strFieldName) == adChar
  1573. || GetFieldType(strFieldName) == adLongVarChar
  1574. || GetFieldType(strFieldName) == adVarWChar
  1575. || GetFieldType(strFieldName) == adWChar
  1576. || GetFieldType(strFieldName) == adLongVarWChar))
  1577. TRACE(_T("Warning: 你要存贮的字段与变量的数据类型不符; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1578. #endif
  1579. _variant_t vt;
  1580. vt.vt = value.IsEmpty() ? VT_NULL : VT_BSTR;
  1581. vt.bstrVal = value.AllocSysString();
  1582. return PutCollect(strFieldName, vt);
  1583. }
  1584. /*########################################################################
  1585.   ------------------------------------------------
  1586.     读取字段的值
  1587.   ------------------------------------------------
  1588.   ########################################################################*/
  1589. BOOL CAdoRecordSet::GetCollect(long index, COleDateTime &value)
  1590. {
  1591. ASSERT(m_pRecordset != NULL);
  1592. try
  1593. {
  1594. value = vartodate(m_pRecordset->GetCollect(_variant_t(index)));
  1595. return TRUE;
  1596. }
  1597. catch (_com_error e)
  1598. {
  1599. value.SetStatus(COleDateTime::null);
  1600. return FALSE;
  1601. }
  1602. }
  1603. BOOL CAdoRecordSet::GetCollect(LPCTSTR strFieldName, COleDateTime &value)
  1604. {
  1605. ASSERT(m_pRecordset != NULL);
  1606. try
  1607. {
  1608. value = vartodate(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1609. return TRUE;
  1610. }
  1611. catch (_com_error e)
  1612. {
  1613. value.SetStatus(COleDateTime::null);
  1614. return FALSE;
  1615. }
  1616. }
  1617. BOOL CAdoRecordSet::GetCollect(long index, COleCurrency &value)
  1618. {
  1619. ASSERT(m_pRecordset != NULL);
  1620. try
  1621. {
  1622. value = vartocy(m_pRecordset->GetCollect(_variant_t(index)));
  1623. return TRUE;
  1624. }
  1625. catch (_com_error e)
  1626. {
  1627. value.m_status = COleCurrency::null;
  1628. return FALSE;
  1629. }
  1630. }
  1631. BOOL CAdoRecordSet::GetCollect(LPCTSTR strFieldName, COleCurrency &value)
  1632. {
  1633. ASSERT(m_pRecordset != NULL);
  1634. try
  1635. {
  1636. value = vartocy(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1637. return TRUE;
  1638. }
  1639. catch (_com_error e)
  1640. {
  1641. value.m_status = COleCurrency::null;
  1642. return FALSE;
  1643. }
  1644. }
  1645. BOOL CAdoRecordSet::GetCollect(long index,  bool &value)
  1646. {
  1647. ASSERT(m_pRecordset != NULL);
  1648. try
  1649. {
  1650. value = vartobool(m_pRecordset->GetCollect(_variant_t(index)));
  1651. return TRUE;
  1652. }
  1653. catch (_com_error e)
  1654. {
  1655. value = false;
  1656. return FALSE;
  1657. }
  1658. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  bool &value)
  1659. {
  1660. ASSERT(m_pRecordset != NULL);
  1661. try
  1662. {
  1663. value = vartobool(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1664. return TRUE;
  1665. }
  1666. catch (_com_error e)
  1667. {
  1668. value = false;
  1669. return FALSE;
  1670. }
  1671. BOOL CAdoRecordSet::GetCollect(long index,  BYTE &value)
  1672. {
  1673. ASSERT(m_pRecordset != NULL);
  1674. try
  1675. {
  1676. value = vartoby(m_pRecordset->GetCollect(_variant_t(index)));
  1677. return TRUE;
  1678. }
  1679. catch (_com_error e)
  1680. {
  1681. value = 0;
  1682. return FALSE;
  1683. }
  1684. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  BYTE &value)
  1685. {
  1686. ASSERT(m_pRecordset != NULL);
  1687. try
  1688. {
  1689. value = vartoby(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1690. return TRUE;
  1691. }
  1692. catch (_com_error e)
  1693. {
  1694. value = 0;
  1695. return FALSE;
  1696. }
  1697. BOOL CAdoRecordSet::GetCollect(long index,  short &value)
  1698. {
  1699. ASSERT(m_pRecordset != NULL);
  1700. try
  1701. {
  1702. value = vartoi(m_pRecordset->GetCollect(_variant_t(index)));
  1703. return TRUE;
  1704. }
  1705. catch (_com_error e)
  1706. {
  1707. value = 0;
  1708. return FALSE;
  1709. }
  1710. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  short &value)
  1711. {
  1712. ASSERT(m_pRecordset != NULL);
  1713. try
  1714. {
  1715. value = vartoi(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1716. return TRUE;
  1717. }
  1718. catch (_com_error e)
  1719. {
  1720. value = 0;
  1721. return FALSE;
  1722. }
  1723. BOOL CAdoRecordSet::GetCollect(long index,  int &value)
  1724. {
  1725. ASSERT(m_pRecordset != NULL);
  1726. try
  1727. {
  1728. value = (int)vartol(m_pRecordset->GetCollect(_variant_t(index)));
  1729. return TRUE;
  1730. }
  1731. catch (_com_error e)
  1732. {
  1733. value = 0;
  1734. return FALSE;
  1735. return FALSE;
  1736. }
  1737. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  int &value)
  1738. {
  1739. ASSERT(m_pRecordset != NULL);
  1740. try
  1741. {
  1742. value = (int)vartol(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1743. return TRUE;
  1744. }
  1745. catch (_com_error e)
  1746. {
  1747. value = 0;
  1748. return FALSE;
  1749. }
  1750. BOOL CAdoRecordSet::GetCollect(long index,  long &value)
  1751. {
  1752. ASSERT(m_pRecordset != NULL);
  1753. try
  1754. {
  1755. value = vartol(m_pRecordset->GetCollect(_variant_t(index)));
  1756. return TRUE;
  1757. }
  1758. catch (_com_error e)
  1759. {
  1760. value = 0;
  1761. return FALSE;
  1762. }
  1763. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  long &value)
  1764. {
  1765. ASSERT(m_pRecordset != NULL);
  1766. try
  1767. {
  1768. value = vartol(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1769. return TRUE;
  1770. }
  1771. catch (_com_error e)
  1772. {
  1773. value = 0;
  1774. return FALSE;
  1775. return FALSE;
  1776. }
  1777. BOOL CAdoRecordSet::GetCollect(long index,  DWORD &value)
  1778. {
  1779. ASSERT(m_pRecordset != NULL);
  1780. try
  1781. {
  1782. _variant_t result = m_pRecordset->GetCollect(_variant_t(index));
  1783. switch (result.vt)
  1784. {
  1785. case VT_UI4:
  1786. case VT_I4:
  1787. value = result.ulVal;
  1788. break;
  1789. case VT_NULL:
  1790. case VT_EMPTY:
  1791. value = 0;
  1792. break;
  1793. default:
  1794. TRACE(_T("Warning: 无法读取相应的字段, 数据类型不匹配; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1795. return FALSE;
  1796. }
  1797. return TRUE;
  1798. }
  1799. catch (_com_error e)
  1800. {
  1801. value = 0;
  1802. return FALSE;
  1803. }
  1804. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  DWORD &value)
  1805. {
  1806. ASSERT(m_pRecordset != NULL);
  1807. try
  1808. {
  1809. _variant_t result = m_pRecordset->GetCollect(_variant_t(strFieldName));
  1810. switch (result.vt)
  1811. {
  1812. case VT_UI4:
  1813. case VT_I4:
  1814. value = result.ulVal;
  1815. break;
  1816. case VT_NULL:
  1817. case VT_EMPTY:
  1818. value = 0;
  1819. break;
  1820. default:
  1821. TRACE(_T("Warning: 无法读取相应的字段, 数据类型不匹配; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1822. return FALSE;
  1823. }
  1824. return TRUE;
  1825. }
  1826. catch (_com_error e)
  1827. {
  1828. value = 0;
  1829. return FALSE;
  1830. }
  1831. BOOL CAdoRecordSet::GetCollect(long index,  float &value)
  1832. {
  1833. ASSERT(m_pRecordset != NULL);
  1834. try
  1835. {
  1836. _variant_t result = m_pRecordset->GetCollect(_variant_t(index));
  1837. switch (result.vt)
  1838. {
  1839. case VT_R4:
  1840. value = result.fltVal;
  1841. break;
  1842. case VT_UI1:
  1843. case VT_I1:
  1844. value = result.bVal;
  1845. break;
  1846. case VT_UI2:
  1847. case VT_I2:
  1848. value = result.iVal;
  1849. break;
  1850. case VT_NULL:
  1851. case VT_EMPTY:
  1852. value = 0;
  1853. break;
  1854. default:
  1855. TRACE(_T("Warning: 无法读取相应的字段, 数据类型不匹配; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1856. return FALSE;
  1857. }
  1858. return TRUE;
  1859. }
  1860. catch (_com_error e)
  1861. {
  1862. value = 0;
  1863. return FALSE;
  1864. }
  1865. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  float &value)
  1866. {
  1867. ASSERT(m_pRecordset != NULL);
  1868. try
  1869. {
  1870. _variant_t result = m_pRecordset->GetCollect(_variant_t(strFieldName));
  1871. switch (result.vt)
  1872. {
  1873. case VT_R4:
  1874. value = result.fltVal;
  1875. break;
  1876. case VT_UI1:
  1877. case VT_I1:
  1878. value = result.bVal;
  1879. break;
  1880. case VT_UI2:
  1881. case VT_I2:
  1882. value = result.iVal;
  1883. break;
  1884. case VT_NULL:
  1885. case VT_EMPTY:
  1886. value = 0;
  1887. break;
  1888. default:
  1889. TRACE(_T("Warning: 无法读取相应的字段, 数据类型不匹配; 文件: %s; 行: %dn"), __FILE__, __LINE__);
  1890. return FALSE;
  1891. }
  1892. return TRUE;
  1893. }
  1894. catch (_com_error e)
  1895. {
  1896. value = 0;
  1897. return FALSE;
  1898. }
  1899. BOOL CAdoRecordSet::GetCollect(long index,  double &value)
  1900. {
  1901. ASSERT(m_pRecordset != NULL);
  1902. try
  1903. {
  1904. value = vartof(m_pRecordset->GetCollect(_variant_t(index)));
  1905. return TRUE;
  1906. }
  1907. catch (_com_error e)
  1908. {
  1909. value = 0;
  1910. return FALSE;
  1911. }
  1912. BOOL CAdoRecordSet::GetCollect(LPCSTR strFieldName,  double &value)
  1913. {
  1914. ASSERT(m_pRecordset != NULL);
  1915. try
  1916. {
  1917. value = vartof(m_pRecordset->GetCollect(_variant_t(strFieldName)));
  1918. return TRUE;
  1919. }
  1920. catch (_com_error e)
  1921. {
  1922. value = 0;
  1923. return FALSE;
  1924. }
  1925. BOOL CAdoRecordSet::GetCollect(long index, CString& strValue)
  1926. {
  1927. ASSERT(m_pRecordset != NULL);
  1928. if (index < 0 || index >= GetFieldsCount())
  1929. {
  1930. return FALSE;
  1931. }
  1932. try
  1933. {
  1934. if (!IsOpen())
  1935. {
  1936. MessageBox(NULL, _T("数据库可能已经断开,rn请重新连接、然后重试."), _T("提示"), MB_ICONINFORMATION);
  1937. return FALSE;
  1938. if (m_pRecordset->adoEOF)
  1939. {
  1940. return FALSE;
  1941. }
  1942. _variant_t value = m_pRecordset->GetCollect(_variant_t(index));
  1943. strValue = vartostr(value);
  1944. return TRUE;
  1945. }
  1946. catch (_com_error e)
  1947. {
  1948. TRACE(_T("Warning: 字段访问失败. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1949. return FALSE;
  1950. }
  1951. return FALSE;
  1952. }
  1953. BOOL CAdoRecordSet::GetCollect(LPCTSTR strFieldName, CString &strValue)
  1954. {
  1955. ASSERT(m_pRecordset != NULL);
  1956. try
  1957. {
  1958. if (!IsOpen())
  1959. {
  1960. MessageBox(NULL, _T("数据库可能已经断开,rn请重新连接、然后重试."), _T("提示"), MB_ICONINFORMATION);
  1961. return FALSE;
  1962. if (m_pRecordset->adoEOF)
  1963. {
  1964. return FALSE;
  1965. }
  1966. _variant_t value = m_pRecordset->GetCollect(_variant_t(LPCTSTR(strFieldName)));
  1967. strValue = vartostr(value);
  1968. return TRUE;
  1969. }
  1970. catch (_com_error e)
  1971. {
  1972. TRACE(_T("Warning: 字段访问失败. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  1973. return FALSE;
  1974. }
  1975. return FALSE;
  1976. }
  1977. /*########################################################################
  1978.   ------------------------------------------------
  1979. 将数据追加到大型文本、二进制数据 Field 对象. 
  1980.   ------------------------------------------------
  1981.   ########################################################################*/
  1982. BOOL CAdoRecordSet::AppendChunk(FieldPtr pField, LPVOID lpData, UINT nBytes)
  1983. {
  1984. SAFEARRAY FAR *pSafeArray = NULL;
  1985. SAFEARRAYBOUND rgsabound[1];
  1986. try
  1987. {
  1988. rgsabound[0].lLbound = 0;
  1989. rgsabound[0].cElements = nBytes;
  1990. pSafeArray = SafeArrayCreate(VT_UI1, 1, rgsabound);
  1991. for (long i = 0; i < (long)nBytes; i++)
  1992. {
  1993. UCHAR &chData = ((UCHAR*)lpData)[i];
  1994. HRESULT hr = SafeArrayPutElement(pSafeArray, &i, &chData);
  1995. if (FAILED(hr)) return FALSE;
  1996. }
  1997. _variant_t varChunk;
  1998. varChunk.vt = VT_ARRAY | VT_UI1;
  1999. varChunk.parray = pSafeArray;
  2000. return (pField->AppendChunk(varChunk) == S_OK);
  2001. }
  2002. catch (_com_error &e)
  2003. {
  2004. TRACE(_T("Warning: AppendChunk 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2005. return FALSE;
  2006. }
  2007. }
  2008. BOOL CAdoRecordSet::AppendChunk(long index, LPVOID lpData, UINT nBytes)
  2009. {
  2010. ASSERT(m_pRecordset != NULL);
  2011. ASSERT(lpData != NULL);
  2012. if (adFldLong & GetFieldAttributes(index))
  2013. {
  2014. return AppendChunk(GetField(index), lpData, nBytes);
  2015. }
  2016. else return FALSE;
  2017. }
  2018. BOOL CAdoRecordSet::AppendChunk(LPCSTR strFieldName, LPVOID lpData, UINT nBytes)
  2019. {
  2020. ASSERT(m_pRecordset != NULL);
  2021. ASSERT(lpData != NULL);
  2022. if (adFldLong & GetFieldAttributes(strFieldName))
  2023. {
  2024. return AppendChunk(GetField(strFieldName), lpData, nBytes);
  2025. }
  2026. else return FALSE;
  2027. }
  2028. BOOL CAdoRecordSet::AppendChunk(long index, LPCTSTR lpszFileName)
  2029. {
  2030. ASSERT(m_pRecordset != NULL);
  2031. ASSERT(lpszFileName != NULL);
  2032. BOOL bret = FALSE;
  2033. if (adFldLong & GetFieldAttributes(index))
  2034. {
  2035. CFile file;
  2036. if (file.Open(lpszFileName, CFile::modeRead))
  2037. {
  2038. long length = (long)file.GetLength();
  2039. char *pbuf = new char[length];
  2040. if (pbuf != NULL && file.Read(pbuf, length) == (DWORD)length)
  2041. {
  2042. bret = AppendChunk(GetField(index), pbuf, length);
  2043. }
  2044. if (pbuf != NULL) delete[] pbuf;
  2045. }
  2046. file.Close();
  2047. }
  2048. return bret;
  2049. }
  2050. BOOL CAdoRecordSet::AppendChunk(LPCSTR strFieldName, LPCTSTR lpszFileName)
  2051. {
  2052. ASSERT(m_pRecordset != NULL);
  2053. ASSERT(lpszFileName != NULL);
  2054. BOOL bret = FALSE;
  2055. if (adFldLong & GetFieldAttributes(strFieldName))
  2056. {
  2057. CFile file;
  2058. if (file.Open(lpszFileName, CFile::modeRead))
  2059. {
  2060. long length = (long)file.GetLength();
  2061. char *pbuf = new char[length];
  2062. if (pbuf != NULL && file.Read(pbuf, length) == (DWORD)length)
  2063. {
  2064. bret = AppendChunk(GetField(strFieldName), pbuf, length);
  2065. }
  2066. if (pbuf != NULL) delete[] pbuf;
  2067. }
  2068. file.Close();
  2069. }
  2070. return bret;
  2071. }
  2072. BOOL CAdoRecordSet::GetChunk(FieldPtr pField, LPVOID lpData)
  2073. {
  2074. ASSERT(pField != NULL);
  2075. ASSERT(lpData != NULL);
  2076. UCHAR chData;
  2077. long index = 0;
  2078. while (index < pField->ActualSize)
  2079. try
  2080. {
  2081. _variant_t varChunk = pField->GetChunk(100);
  2082. if (varChunk.vt != (VT_ARRAY | VT_UI1))
  2083. {
  2084. return FALSE;
  2085. }
  2086.             for (long i = 0; i < 100; i++)
  2087.             {
  2088.                 if (SUCCEEDED( SafeArrayGetElement(varChunk.parray, &i, &chData) ))
  2089.                 {
  2090. ((UCHAR*)lpData)[index] = chData;
  2091.                     index++;
  2092.                 }
  2093.                 else
  2094. {
  2095.                     break;
  2096. }
  2097.             }
  2098. }
  2099. catch (_com_error e)
  2100. {
  2101. TRACE(_T("Warning: GetChunk 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2102. return FALSE;
  2103. }
  2104. }
  2105. return TRUE;
  2106. }
  2107. BOOL CAdoRecordSet::GetChunk(long index, LPVOID lpData)
  2108. {
  2109. if (adFldLong & GetFieldAttributes(index))
  2110. return  GetChunk(GetField(index), lpData);
  2111. else return FALSE;
  2112. }
  2113. BOOL CAdoRecordSet::GetChunk(LPCSTR strFieldName, LPVOID lpData)
  2114. {
  2115. if (adFldLong & GetFieldAttributes(strFieldName))
  2116. return  GetChunk(GetField(strFieldName), lpData);
  2117. else return FALSE;
  2118. }
  2119. BOOL CAdoRecordSet::GetChunk(long index, CBitmap &bitmap)
  2120. {
  2121. return GetChunk(GetFieldName(index), bitmap);
  2122. }
  2123. BOOL CAdoRecordSet::GetChunk(LPCSTR strFieldName, CBitmap &bitmap)
  2124. {
  2125. BOOL bret = FALSE;
  2126. long size = GetFieldActualSize(strFieldName);
  2127. if ((adFldLong & GetFieldAttributes(strFieldName)) && size > 0)
  2128. {
  2129. BYTE *lpData = new BYTE[size];
  2130. if (GetChunk(GetField(strFieldName), (LPVOID)lpData))
  2131. {
  2132. BITMAPFILEHEADER bmpHeader;
  2133. DWORD bmfHeaderLen = sizeof(bmpHeader);
  2134. strncpy((LPSTR)&bmpHeader, (LPSTR)lpData, bmfHeaderLen);
  2135. // 是否是位图 ----------------------------------------
  2136. if (bmpHeader.bfType == (*(WORD*)"BM"))
  2137. {
  2138. BYTE* lpDIBBits = lpData + bmfHeaderLen;
  2139. BITMAPINFOHEADER &bmpiHeader = *(LPBITMAPINFOHEADER)lpDIBBits;
  2140. BITMAPINFO &bmpInfo = *(LPBITMAPINFO)lpDIBBits;
  2141. lpDIBBits = lpData + ((BITMAPFILEHEADER *)lpData)->bfOffBits;
  2142. // 创建位图 --------------------------------------
  2143. CDC dc;
  2144. HDC hdc = GetDC(NULL);
  2145. dc.Attach(hdc);
  2146. HBITMAP hBmp = CreateDIBitmap(dc.m_hDC, &bmpiHeader, CBM_INIT, lpDIBBits, &bmpInfo, DIB_RGB_COLORS);
  2147. if (bitmap.GetSafeHandle() != NULL) bitmap.DeleteObject();
  2148. bitmap.Attach(hBmp);
  2149. dc.Detach();
  2150. ReleaseDC(NULL, hdc);
  2151. bret = TRUE;
  2152. }
  2153. }
  2154. delete[] lpData;
  2155. lpData = NULL;
  2156. }
  2157. return bret;
  2158. }
  2159. /*########################################################################
  2160.   ------------------------------------------------
  2161.    其他方法
  2162.   ------------------------------------------------
  2163.   ########################################################################*/
  2164. _RecordsetPtr CAdoRecordSet::operator =(_RecordsetPtr &pRecordSet)
  2165. {
  2166. Close();
  2167. if (pRecordSet != NULL)
  2168. {
  2169. m_pRecordset = NULL;
  2170. m_pRecordset = pRecordSet;
  2171. return m_pRecordset;
  2172. }
  2173. return NULL;
  2174. }
  2175. /*========================================================================
  2176. Name: 确定指定的 Recordset 对象是否支持特定类型的功能.
  2177.     ----------------------------------------------------------
  2178. Params: CursorOptions   长整型, 包括一个或多个下列 CursorOptionEnum 值.
  2179. [常量] [说明] 
  2180. ------------------------------------
  2181. adAddNew 可使用 AddNew 方法添加新记录. 
  2182. adApproxPosition 可读取并设置 AbsolutePosition 和 AbsolutePage 的属性. 
  2183. adBookmark 可使用 Bookmark 属性获得对特定记录的访问. 
  2184. adDelete 可以使用 Delete 方法删除记录. 
  2185. adHoldRecords 可以检索多个记录或者更改下一个检索位置而不必提交所
  2186. 有挂起的更改. 
  2187. adMovePrevious 可使用 MoveFirst 和 MovePrevious 方法, 以及 Move 或
  2188. GetRows 方法将当前记录位置向后移动而不必使用书签. 
  2189. adResync 通过 Resync 方法, 使用在基本的数据库中可见的数据更
  2190. 新游标. 
  2191. adUpdate 可使用 Update 方法修改现有的数据. 
  2192. adUpdateBatch 可以使用批更新(UpdateBatch 和 CancelBatch 方法) 将
  2193. 更改组传输给提供者. 
  2194. adIndex 可以使用 Index 属性命名索引. 
  2195. adSeek 可以使用 Seek 方法定位 Recordset 中的行. 
  2196.     ----------------------------------------------------------
  2197. returns: 返回布尔型值, 指示是否支持 CursorOptions 参数所标识的所有功能.
  2198.     ----------------------------------------------------------
  2199. Remarks: 使用 Supports 方法确定 Recordset 对象所支持的功能类型. 如
  2200. 果 Recordset 对象支持其相应常量在 CursorOptions 中的功能, 那么 Supports
  2201. 方法返回 True.否则返回 False.
  2202. 注意   尽管 Supports 方法可对给定的功能返回 True, 但它不能保证提供者可
  2203. 以使功能在所有环境下均有效. Supports 方法只返回提供者是否支持指定的功能
  2204. (假定符合某些条件). 例如, Supports 方法可能指示 Recordset 对象支持更新
  2205. (即使游标基于多个表的合并), 但并且某些列仍然无法更新.
  2206. ==========================================================================*/
  2207. BOOL CAdoRecordSet::Supports(CursorOptionEnum CursorOptions)
  2208. {
  2209. ASSERT(m_pRecordset != NULL);
  2210. try
  2211. {
  2212. if (m_pRecordset != NULL)
  2213. {
  2214. return m_pRecordset->Supports(CursorOptions);
  2215. }
  2216. }
  2217. catch (const _com_error& e)
  2218. {
  2219. TRACE(_T("Warning: Supports方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2220. return FALSE;
  2221. }
  2222. return FALSE;
  2223. }
  2224. /*========================================================================
  2225. name: 为 Recordset 中的数据指定筛选条件.
  2226. ==========================================================================*/
  2227. BOOL CAdoRecordSet::SetFilter(LPCTSTR lpszFilter)
  2228. {
  2229. ASSERT(m_pRecordset != NULL);
  2230. ASSERT(IsOpen());
  2231. try
  2232. {
  2233. m_pRecordset->PutFilter(lpszFilter);
  2234. return TRUE;
  2235. }
  2236. catch (_com_error e)
  2237. {
  2238. TRACE(_T("Warning: SetFilter 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2239. return FALSE;
  2240. }
  2241. }
  2242. /*========================================================================
  2243. name: 为 Recordset 中的数据指定排序条件.
  2244. ==========================================================================*/
  2245. BOOL CAdoRecordSet::SetSort(LPCTSTR lpszCriteria)
  2246. {
  2247. ASSERT(IsOpen());
  2248. try
  2249. {
  2250. m_pRecordset->PutSort(lpszCriteria);
  2251. return TRUE;
  2252. }
  2253. catch (_com_error e)
  2254. {
  2255. TRACE(_T("Warning: SetFilter 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2256. return FALSE;
  2257. }
  2258. }
  2259. /*========================================================================
  2260. name: 返回唯一标识 Recordset 对象中当前记录的书签。
  2261. ==========================================================================*/
  2262. _variant_t CAdoRecordSet::GetBookmark()
  2263. {
  2264. ASSERT(m_pRecordset != NULL);
  2265. try
  2266. {
  2267. if (IsOpen())
  2268. {
  2269. m_varBookmark = m_pRecordset->GetBookmark();
  2270. return m_varBookmark;
  2271. }
  2272. }
  2273. catch (_com_error e)
  2274. {
  2275. TRACE(_T("Warning: GetBookmark 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2276. }
  2277. return _variant_t((long)adBookmarkFirst);
  2278. }
  2279. /*========================================================================
  2280. name: 将 Recordset 对象的当前记录设置为由有效书签所标识的记录。
  2281. ==========================================================================*/
  2282. BOOL CAdoRecordSet::SetBookmark(_variant_t varBookMark)
  2283. {
  2284. ASSERT(m_pRecordset != NULL);
  2285. try
  2286. {
  2287. if (IsOpen() && varBookMark.vt != VT_EMPTY && varBookMark.vt != VT_NULL)
  2288. {
  2289. m_pRecordset->PutBookmark(varBookMark);
  2290. return TRUE;
  2291. }
  2292. }
  2293. catch (_com_error e)
  2294. {
  2295. TRACE(_T("Warning: SetBookmark 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2296. }
  2297. return FALSE;
  2298. }
  2299. void CAdoRecordSet::SetAdoConnection(CAdoConnection *pConnection)
  2300. {
  2301. m_pConnection = pConnection;
  2302. }
  2303. _RecordsetPtr& CAdoRecordSet::GetRecordset()
  2304. {
  2305. return m_pRecordset;
  2306. }
  2307. CString CAdoRecordSet::GetLastError()
  2308. {
  2309. ASSERT(m_pConnection != NULL);
  2310. return m_pConnection->GetLastErrorText();
  2311. }
  2312. /*========================================================================
  2313. name: 创建与现有 Recordset 对象相同的复制 Recordset 对象。可选择指定
  2314. 该副本为只读。
  2315. ==========================================================================*/
  2316. BOOL CAdoRecordSet::Clone(CAdoRecordSet &pRecordSet)
  2317. {
  2318. ASSERT(m_pRecordset != NULL);
  2319. try
  2320. {
  2321. pRecordSet = m_pRecordset->Clone(adLockUnspecified);
  2322. return TRUE;
  2323. }
  2324. catch (_com_error e)
  2325. {
  2326. TRACE(_T("Warning: Clone 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2327. return FALSE;
  2328. }
  2329. }
  2330. /*========================================================================
  2331. name: 搜索 Recordset 中满足指定标准的记录. 如果满足标准,则记录集
  2332. 位置设置在找到的记录上,否则位置将设置在记录集的末尾. 
  2333.     ----------------------------------------------------------
  2334. params: [criteria]:   字符串,包含指定用于搜索的列名、比较操作符和
  2335. 值的语句. 
  2336. [searchDirection]:    可选的 SearchDirectionEnum 值,指定搜
  2337. 索应从当前行还是下一个有效行开始. 其值可为 adSearchForward 或 adSearchBackward. 
  2338. 搜索是在记录集的开始还是末尾结束由 searchDirection 值决定. 
  2339. [常量] [说明]
  2340. ---------------------------------
  2341. adSearchForward 
  2342. adSearchBackward
  2343.     ----------------------------------------------------------
  2344. Remarks: criteria 中的"比较操作符"可以是">"(大于)、"<"(小于)、"="(等
  2345. 于)、">="(大于或等于)、"<="(小于或等于)、"<>"(不等于)或"like"(模式匹配).  
  2346. criteria 中的值可以是字符串、浮点数或者日期. 字符串值以单引号分界(如
  2347. "state = 'WA'"). 日期值以"#"(数字记号)分界(如"start_date > #7/22/97#"). 
  2348. 如"比较操作符"为"like",则字符串"值"可以包含"*"(某字符可出现一次或
  2349. 多次)或者"_"(某字符只出现一次). (如"state like M_*"与 Maine 和 Massachusetts 
  2350. 匹配.). 
  2351. ==========================================================================*/
  2352. BOOL CAdoRecordSet::Find(LPCTSTR lpszFind, SearchDirectionEnum SearchDirection)
  2353. {
  2354. ASSERT(m_pRecordset != NULL);
  2355. ASSERT(AfxIsValidString(lpszFind));
  2356. try
  2357. {
  2358. if (strcmp(lpszFind, _T("")) != 0)
  2359. {
  2360. m_strFind = lpszFind;
  2361. }
  2362. if (m_strFind.IsEmpty()) return FALSE;
  2363. m_pRecordset->Find(_bstr_t(m_strFind), 0, SearchDirection, "");
  2364. if ((IsEOF() || IsBOF()) )
  2365. {
  2366. return FALSE;
  2367. }
  2368. else
  2369. {
  2370. m_SearchDirection = SearchDirection;
  2371. GetBookmark();
  2372. return TRUE;
  2373. }
  2374. }
  2375. catch (_com_error e)
  2376. {
  2377. TRACE(_T("Warning: Find 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2378. return FALSE;
  2379. }
  2380. }
  2381. /*========================================================================
  2382. name: 查找下一条满足条件的记录.
  2383. ==========================================================================*/
  2384. BOOL CAdoRecordSet::FindNext()
  2385. {
  2386. ASSERT(m_pRecordset != NULL);
  2387. try
  2388. {
  2389. if (m_strFind.IsEmpty()) return FALSE;
  2390. m_pRecordset->Find(_bstr_t(m_strFind), 1, m_SearchDirection, m_varBookmark);
  2391. if ((IsEOF() || IsBOF()) )
  2392. {
  2393. return FALSE;
  2394. }
  2395. else
  2396. {
  2397. GetBookmark();
  2398. return TRUE;
  2399. }
  2400. }
  2401. catch (_com_error e)
  2402. {
  2403. TRACE(_T("Warning: FindNext 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2404. return FALSE;
  2405. }
  2406. }
  2407. BOOL CAdoRecordSet::RecordBinding(CADORecordBinding &pAdoRecordBinding)
  2408. {
  2409. m_pAdoRecordBinding = NULL;
  2410. try
  2411. {
  2412. if (SUCCEEDED(m_pRecordset->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&m_pAdoRecordBinding)))
  2413. {
  2414. if (SUCCEEDED(m_pAdoRecordBinding->BindToRecordset(&pAdoRecordBinding)))
  2415. {
  2416. return TRUE;
  2417. }
  2418. }
  2419. return TRUE;
  2420. }
  2421. catch (_com_error e)
  2422. {
  2423. TRACE(_T("Warning: RecordBinding 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2424. return FALSE;
  2425. }
  2426. }
  2427. BOOL CAdoRecordSet::AddNew(CADORecordBinding &pAdoRecordBinding)
  2428. {
  2429. try
  2430. {
  2431. if (m_pAdoRecordBinding->AddNew(&pAdoRecordBinding) == S_OK)
  2432. {
  2433. m_pAdoRecordBinding->Update(&pAdoRecordBinding);
  2434. return TRUE;
  2435. }
  2436. return FALSE;
  2437. }
  2438. catch (_com_error e)
  2439. {
  2440. TRACE(_T("Warning: AddNew 方法发生异常. 错误信息: %s; 文件: %s; 行: %dn"), e.ErrorMessage(), __FILE__, __LINE__);
  2441. return FALSE;
  2442. }
  2443. }
  2444. /*========================================================================
  2445. Name: 获得当前游标位置
  2446. -----------------------------------------------------
  2447. Remarks: 返回位置。
  2448. ==========================================================================*/
  2449. long CAdoRecordSet::GetCursorPos()
  2450. {
  2451. long count = m_pRecordset->GetRecordCount();
  2452. while (!m_pRecordset->adoEOF)
  2453. {
  2454. m_pRecordset->MoveNext();
  2455. count--;
  2456. }
  2457. m_pRecordset->MoveFirst();
  2458. m_pRecordset->Move(count);
  2459. return count;
  2460. }
  2461. /*========================================================================
  2462. Name: 获得指定列在集合中的位置。
  2463. -----------------------------------------------------
  2464. params: filedName   列名
  2465. ---------------------------------
  2466. ==========================================================================*/
  2467. int CAdoRecordSet::GetFieldIndex(CString filedName)
  2468. {
  2469. long colCount = GetFieldsCount();
  2470. for (int i = 0 ;i < colCount; i++)
  2471. {
  2472. if (filedName == GetFieldName(i))
  2473. {
  2474. break;
  2475. }
  2476. }
  2477. return i == colCount ?-1:i;
  2478. }
  2479. /*========================================================================
  2480. Name: 获取记录集合中指定列的字符串形式的值
  2481. -----------------------------------------------------
  2482. params: index   列在集合中的位置
  2483.         lockCursorPos   为TRUE时,保持游标原来的位置不变
  2484. maxRows    一次返回记录的最大行
  2485. ---------------------------------
  2486. remarks: 如果lockCursorPos为TRUE时,保持游标原来的位置不变,所以重复调用该函数返回
  2487.          内容一样。考虑到如果记录集合中记录数较多,array数组很大,会占用较多的系统
  2488.  资源,所以对它进行优化:
  2489.      当lockCursorPos 为FALSE 时,将从当前记录开始,返回maxRows条记录的值。
  2490. ==========================================================================*/
  2491. BOOL CAdoRecordSet::GetFieldValues(CStringArray *array, int index ,BOOL lockCursorPos,int maxRows)
  2492. {
  2493. BOOL flag(TRUE);
  2494. long pos ;
  2495. long count = m_pRecordset->GetRecordCount();
  2496. long colCount = GetFieldsCount();
  2497. if (count <=0 || index >= colCount || index <0) //check values
  2498. {
  2499.      #ifdef _DEBUG
  2500. if (count <=0 )
  2501. TRACE(_T("记录集合为空"));
  2502. else
  2503. TRACE(_T("超出字段范围"));
  2504.      #endif
  2505. return FALSE;
  2506. }
  2507. //
  2508. if (lockCursorPos)
  2509. {
  2510. pos= GetCursorPos();
  2511. }
  2512. array->RemoveAll();
  2513. // m_pRecordset->MoveFirst();
  2514. for (int i = 0 ;i < maxRows ;i ++)
  2515. {
  2516. CString temp;
  2517. if (!GetCollect(index,temp))
  2518. {
  2519. flag = FALSE;
  2520. TRACE(_T("CAdoRecordSet::GetFieldValues 失败--%s"),GetLastError());
  2521. break;
  2522. }
  2523. array->Add(temp);
  2524. if (m_pRecordset->adoEOF)
  2525. {
  2526. flag = FALSE;
  2527. break;
  2528. }
  2529. m_pRecordset->MoveNext();
  2530. }
  2531. if (lockCursorPos)
  2532. {
  2533. m_pRecordset->MoveFirst();
  2534. m_pRecordset->Move(pos);
  2535. }
  2536. return flag;
  2537. }
  2538. BOOL CAdoRecordSet::GetFieldValues(CStringArray *array, CString fieldName,BOOL lockCursorPos ,int maxRows)
  2539. {
  2540. int index =GetFieldIndex(fieldName);
  2541. return GetFieldValues(array,index,lockCursorPos,maxRows);
  2542. }
  2543. /*========================================================================
  2544. Name: 获取记录集合中指定列的字符串形式的值
  2545. -----------------------------------------------------
  2546. params: index   列在集合中的位置
  2547.         lockCursorPos   为TRUE时,保持游标原来的位置不变
  2548. maxRows    一次返回记录的最大行
  2549. size        Array数组大小
  2550. ---------------------------------
  2551. remarks: 如果lockCursorPos为TRUE时,保持游标原来的位置不变,所以重复调用该函数返回
  2552.          内容一样。考虑到如果记录集合中记录数较多,array数组很大,会占用较多的系统
  2553.  资源,所以对它进行优化:
  2554.      当lockCursorPos 为FALSE 时,将从当前记录开始,返回maxRows条记录的值。
  2555. ==========================================================================*/
  2556. int CAdoRecordSet::GetFieldValues(int *Array, int size, int index, BOOL lockCursorPos, int maxRows)
  2557. {
  2558. long pos ;
  2559. long count = m_pRecordset->GetRecordCount();
  2560. long colCount = GetFieldsCount();
  2561. if (count <=0 || index >= colCount || index <0) //check values
  2562. {
  2563.      #ifdef _DEBUG
  2564. if (count <=0 )
  2565. TRACE(_T("记录集合为空"));
  2566. else
  2567. TRACE(_T("超出字段范围"));
  2568.      #endif
  2569. return FALSE;
  2570. }
  2571. //
  2572. if (lockCursorPos)
  2573. {
  2574. pos= GetCursorPos();
  2575. }
  2576. for (int i = 0 ;i < maxRows && i < size;)
  2577. {
  2578. int temp;
  2579. if (!GetCollect(index,temp))
  2580. {
  2581. TRACE(_T("CAdoRecordSet::GetFieldValues 失败--%s"),GetLastError());
  2582. break;
  2583. }
  2584. Array[i++] = temp;
  2585. if (m_pRecordset->adoEOF)
  2586. {
  2587. break;
  2588. }
  2589. m_pRecordset->MoveNext();
  2590. }
  2591. if (lockCursorPos)
  2592. {
  2593. m_pRecordset->MoveFirst();
  2594. m_pRecordset->Move(pos);
  2595. }
  2596. return i;
  2597. }
  2598. int CAdoRecordSet::GetFieldValues(int *Array, int size, CString fieldName, BOOL lockCursorPos, int maxRows)
  2599. {
  2600. int index =GetFieldIndex(fieldName);
  2601. return GetFieldValues(Array,size,index,lockCursorPos,maxRows);
  2602. }
  2603. /*========================================================================
  2604. Name: 获取记录集合中指定列的字符串形式的值
  2605. -----------------------------------------------------
  2606. params: index   列在集合中的位置
  2607.         lockCursorPos   为TRUE时,保持游标原来的位置不变
  2608. maxRows    一次返回记录的最大行
  2609. size        Array数组大小
  2610. ---------------------------------
  2611. remarks: 如果lockCursorPos为TRUE时,保持游标原来的位置不变,所以重复调用该函数返回
  2612.          内容一样。考虑到如果记录集合中记录数较多,array数组很大,会占用较多的系统
  2613.  资源,所以对它进行优化:
  2614.      当lockCursorPos 为FALSE 时,将从当前记录开始,返回maxRows条记录的值。
  2615. ==========================================================================*/
  2616. int CAdoRecordSet::GetFieldValues(double *Array, int size, int index, BOOL lockCursorPos, int maxRows)
  2617. {
  2618. long pos ;
  2619. long count = m_pRecordset->GetRecordCount();
  2620. long colCount = GetFieldsCount();
  2621. if (count <=0 || index >= colCount || index <0) //check values
  2622. {
  2623.      #ifdef _DEBUG
  2624. if (count <=0 )
  2625. TRACE(_T("记录集合为空"));
  2626. else
  2627. TRACE(_T("超出字段范围"));
  2628.      #endif
  2629. return FALSE;
  2630. }
  2631. //
  2632. if (lockCursorPos)
  2633. {
  2634. pos= GetCursorPos();
  2635. }
  2636. for (int i = 0 ;i < maxRows && i < size;)
  2637. {
  2638. double temp;
  2639. if (!GetCollect(index,temp))
  2640. {
  2641. TRACE(_T("CAdoRecordSet::GetFieldValues 失败--%s"),GetLastError());
  2642. break;
  2643. }
  2644. Array[i++] = temp;
  2645. if (m_pRecordset->adoEOF)
  2646. {
  2647. break;
  2648. }
  2649. m_pRecordset->MoveNext();
  2650. }
  2651. if (lockCursorPos)
  2652. {
  2653. m_pRecordset->MoveFirst();
  2654. m_pRecordset->Move(pos);
  2655. }
  2656. return i;
  2657. }
  2658. int CAdoRecordSet::GetFieldValues(double *Array, int size, CString fieldName, BOOL lockCursorPos, int maxRows)
  2659. {
  2660. int index =GetFieldIndex(fieldName);
  2661. return GetFieldValues(Array,size,index,lockCursorPos,maxRows);
  2662. }
  2663. /*========================================================================
  2664. Name: 获取记录集合中指定列的字符串形式的值
  2665. -----------------------------------------------------
  2666. params: index   列在集合中的位置
  2667.         lockCursorPos   为TRUE时,保持游标原来的位置不变
  2668. maxRows    一次返回记录的最大行
  2669. size        Array数组大小
  2670. ---------------------------------
  2671. remarks: 如果lockCursorPos为TRUE时,保持游标原来的位置不变,所以重复调用该函数返回
  2672.          内容一样。考虑到如果记录集合中记录数较多,array数组很大,会占用较多的系统
  2673.  资源,所以对它进行优化:
  2674.      当lockCursorPos 为FALSE 时,将从当前记录开始,返回maxRows条记录的值。
  2675. ==========================================================================*/
  2676. int CAdoRecordSet::GetFieldValues(COleDateTime *Array, int size, int index, BOOL lockCursorPos, int maxRows)
  2677. {
  2678. long pos ;
  2679. long count = m_pRecordset->GetRecordCount();
  2680. long colCount = GetFieldsCount();
  2681. if (count <=0 || index >= colCount || index <0) //check values
  2682. {
  2683.      #ifdef _DEBUG
  2684. if (count <=0 )
  2685. TRACE(_T("记录集合为空"));
  2686. else
  2687. TRACE(_T("超出字段范围"));
  2688.      #endif
  2689. return FALSE;
  2690. }
  2691. //
  2692. if (lockCursorPos)
  2693. {
  2694. pos= GetCursorPos();
  2695. }
  2696. for (int i = 0 ;i < maxRows && i < size;)
  2697. {
  2698. COleDateTime temp;
  2699. if (!GetCollect(index,temp))
  2700. {
  2701. TRACE(_T("CAdoRecordSet::GetFieldValues 失败--%s"),GetLastError());
  2702. break;
  2703. }
  2704. Array[i++] = temp;
  2705. if (m_pRecordset->adoEOF)
  2706. {
  2707. break;
  2708. }
  2709. m_pRecordset->MoveNext();
  2710. }
  2711. if (lockCursorPos)
  2712. {
  2713. m_pRecordset->MoveFirst();
  2714. m_pRecordset->Move(pos);
  2715. }
  2716. return i;
  2717. }
  2718. int CAdoRecordSet::GetFieldValues(COleDateTime *Array, int size, CString fieldName, BOOL lockCursorPos, int maxRows)
  2719. {
  2720. int index =GetFieldIndex(fieldName);
  2721. return GetFieldValues(Array,size,index,lockCursorPos,maxRows);
  2722. }
  2723. BOOL CAdoRecordSet::SeekToFieldValue(int fieldIndex, const CString & Value ,BOOL flag)
  2724. {
  2725. if (flag)
  2726. {
  2727. MoveLast();
  2728. CString Fieldvalue;
  2729. while (!IsBOF())
  2730. {
  2731. GetCollect(fieldIndex, Fieldvalue);
  2732. if (Value == Fieldvalue)
  2733. return TRUE;
  2734. MovePrevious();
  2735. }
  2736. return FALSE;
  2737. }
  2738. else
  2739. {
  2740. MoveFirst();
  2741. CString Fieldvalue;
  2742. while (!IsEOF())
  2743. {
  2744. GetCollect(fieldIndex, Fieldvalue);
  2745. if (Value == Fieldvalue)
  2746. return TRUE;
  2747. MoveNext();
  2748. }
  2749. return FALSE;
  2750. }
  2751. }
  2752. BOOL CAdoRecordSet::LoadOLEDataFromDB(CString CreateFileName ,CString feildName)
  2753. {
  2754. long nSize = GetFields()->GetItem(_variant_t(feildName))->ActualSize;
  2755. if(nSize > 0)
  2756. {
  2757. _variant_t varBLOB;
  2758. varBLOB = GetFields()->GetItem(_variant_t(feildName))->GetChunk(nSize);
  2759. if(varBLOB.vt == (VT_ARRAY | VT_UI1))
  2760. {
  2761. CFile file;
  2762. if (!file.Open(CreateFileName,CFile::modeWrite|CFile::modeCreate))
  2763. return FALSE;
  2764. // if(BYTE *pBuffer = new BYTE [nSize+1]) ///重新申请必要的存储空间
  2765. // {
  2766. char *pBuf = NULL;
  2767. SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
  2768. // memcpy(pBuffer,pBuf,nSize); ///复制数据到缓冲区m_pBMPBuffer
  2769. SafeArrayUnaccessData (varBLOB.parray);
  2770. // int nSize = lDataSize;
  2771. // (Pic->LoadPictureData(pBuffer, nSize));
  2772. file.WriteHuge((void*) pBuf,nSize);
  2773. file.Close();
  2774. // delete [] pBuffer;
  2775. pBuf=0;
  2776. // }
  2777. }
  2778. }
  2779. return TRUE;
  2780. }