-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAdoRecordSet.cpp
2716 lines (2494 loc) · 75.1 KB
/
AdoRecordSet.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*########################################################################
Filename: adorecordset.cpp
----------------------------------------------------
Remarks: ...
----------------------------------------------------
Author: 成真
Email: anyou@sina.com
anyou@msn.com
Created: 29/4/2003 8:15
########################################################################*/
#include "stdafx.h"
#include "AdoRecordSet.h"
#include <math.h>
#include <io.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/*########################################################################
------------------------------------------------
CAdoRecordSet class 构造/析构函数
------------------------------------------------
########################################################################*/
CAdoRecordSet::CAdoRecordSet()
{
m_pConnection = NULL;
m_SearchDirection = adSearchForward;
m_pRecordset.CreateInstance("ADODB.Recordset");
#ifdef _DEBUG
if (m_pRecordset == NULL)
{
AfxMessageBox("RecordSet 对象创建失败! 请确认是否初始化了COM环境.");
}
#endif
ASSERT(m_pRecordset != NULL);
}
CAdoRecordSet::CAdoRecordSet(CAdoConnection *pConnection)
{
m_SearchDirection = adSearchForward;
m_pConnection = pConnection;
ASSERT(m_pConnection != NULL);
m_pRecordset.CreateInstance("ADODB.Recordset");
#ifdef _DEBUG
if (m_pRecordset == NULL)
{
AfxMessageBox("RecordSet 对象创建失败! 请确认是否初始化了COM环境.");
}
#endif
ASSERT(m_pRecordset != NULL);
}
CAdoRecordSet::~CAdoRecordSet()
{
Release();
}
/*========================================================================
Params:
- strSQL: SQL语句, 表名, 存储过程调用或持久 Recordset 文件名.
- CursorType: 可选. CursorTypeEnum 值, 确定打开 Recordset 时应该
使用的游标类型. 可为下列常量之一.
[常量] [说明]
-----------------------------------------------
adOpenForwardOnly 打开仅向前类型游标.
adOpenKeyset 打开键集类型游标.
adOpenDynamic 打开动态类型游标.
adOpenStatic 打开静态类型游标.
-----------------------------------------------
- LockType: 可选, 确定打开 Recordset 时应该使用的锁定类型(并发)
的 LockTypeEnum 值, 可为下列常量之一.
[常量] [说明]
-----------------------------------------------
adLockReadOnly 只读 - 不能改变数据.
adLockPessimistic 保守式锁定 - 通常通过在编辑时立即锁定数据源的记录.
adLockOptimistic 开放式锁定 - 只在调用 Update 方法时才锁定记录.
adLockBatchOptimistic 开放式批更新 - 用于批更新模式(与立即更新模式
相对).
-----------------------------------------------
- lOption 可选. 长整型值, 用于指示 strSQL 参数的类型. 可为下
列常量之一.
[常量] [说明]
-------------------------------------------------
adCmdText 指示strSQL为命令文本, 即普通的SQL语句.
adCmdTable 指示ADO生成SQL查询返回以 strSQL 命名的表中的
所有行.
adCmdTableDirect 指示所作的更改在strSQL中命名的表中返回所有行.
adCmdStoredProc 指示strSQL为存储过程.
adCmdUnknown 指示strSQL参数中的命令类型为未知.
adCmdFile 指示应从在strSQL中命名的文件中恢复保留(保存的)
Recordset.
adAsyncExecute 指示应异步执行strSQL.
adAsyncFetch 指示在提取 Initial Fetch Size 属性中指定的初始
数量后, 应该异步提取所有剩余的行. 如果所需的行尚未
提取, 主要的线程将被堵塞直到行重新可用.
adAsyncFetchNonBlocking 指示主要线程在提取期间从未堵塞. 如果所请求
的行尚未提取, 当前行自动移到文件末尾.
==========================================================================*/
BOOL CAdoRecordSet::Open(LPCTSTR strSQL, long lOption, CursorTypeEnum CursorType, LockTypeEnum LockType)
{
ASSERT(m_pConnection != NULL);
ASSERT(m_pRecordset != NULL);
ASSERT(AfxIsValidString(strSQL));
if(strcmp(strSQL, _T("")) != 0)
{
m_strSQL = strSQL;
}
if (m_pConnection == NULL || m_pRecordset == NULL)
{
return FALSE;
}
if (m_strSQL.IsEmpty())
{
ASSERT(FALSE);
return FALSE;
}
try
{
if (IsOpen()) Close();
return SUCCEEDED(m_pRecordset->Open(_variant_t(LPCTSTR(m_strSQL)),
_variant_t((IDispatch*)m_pConnection->GetConnection(), true),
CursorType, LockType, lOption));
}
catch (_com_error e)
{
TRACE(_T("Warning: 打开记录集发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
TRACE(_T("%s\r\n"), GetLastError());
return FALSE;
}
}
/*========================================================================
Name: 通过重新执行对象所基于的查询, 更新 Recordset 对象中的数据.
----------------------------------------------------------
Params: Options 可选. 指示影响该操作选项的位屏蔽. 如果该参数设置
为 adAsyncExecute, 则该操作将异步执行并在它结束时产生
RecordsetChangeComplete 事件
----------------------------------------------------------
Remarks: 通过重新发出原始命令并再次检索数据, 可使用 Requery 方法刷新
来自数据源的 Recordset 对象的全部内容. 调用该方法等于相继调用 Close 和
Open 方法. 如果正在编辑当前记录或者添加新记录将产生错误.
==========================================================================*/
BOOL CAdoRecordSet::Requery(long Options)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->Requery(Options) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Requery 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 从基本数据库刷新当前 Recordset 对象中的数据.
----------------------------------------------------------
Params: AffectRecords: 可选, AffectEnum 值, 决定 Resync 方法所影
响的记录数目, 可以为下列常量之一.
[常量] [说明]
------------------------------------
adAffectCurrent 只刷新当前记录.
adAffectGroup 刷新满足当前 Filter 属性设置的记录.只有将 Filter
属性设置为有效预定义常量之一才能使用该选项.
adAffectAll 默认值.刷新 Recordset 对象中的所有记录, 包括由
于当前 Filter 属性设置而隐藏的记录.
adAffectAllChapters 刷新所有子集记录.
ResyncValues: 可选, ResyncEnum 值. 指定是否覆盖基本值. 可为下列
常量之一.
[常量] [说明]
------------------------------------
adResyncAllValues 默认值. 覆盖数据, 取消挂起的更新.
adResyncUnderlyingValues 不覆盖数据, 不取消挂起的更新.
----------------------------------------------------------
Remarks: 使用 Resync 方法将当前 Recordset 中的记录与基本的数据库重新
同步. 这在使用静态或仅向前的游标但希望看到基本数据库中的改动时十分有用.
如果将 CursorLocation 属性设置为 adUseClient, 则 Resync 仅对非只读的
Recordset 对象可用.
与 Requery 方法不同, Resync 方法不重新执行 Recordset 对象的基本的命令,
基本的数据库中的新记录将不可见.
==========================================================================*/
BOOL CAdoRecordSet::Resync(AffectEnum AffectRecords, ResyncEnum ResyncValues)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->Resync(AffectRecords, ResyncValues) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Resync 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 将 Recordset 保存在持久性文件中.
----------------------------------------------------------
Params:
[strFileName]: 可选. 文件的完整路径名, 用于保存 Recordset.
[PersistFormat]: 可选. PersistFormatEnum 值, 指定保存 Recordset 所使
用的格式. 可以是如下的某个常量:
[常量] [说明]
------------------------------
adPersistADTG 使用专用的"Advanced Data Tablegram"格式保存.
adPersistXML (默认)使用 XML 格式保存.
----------------------------------------------------------
Remarks: 只能对打开的 Recordset 调用 Save 方法. 随后使用 Load 方法可
以从文件中恢复 Recordset. 如果 Filter 属性影响 Recordset, 将只保存经过
筛选的行.
在第一次保存 Recordset 时指定 FileName. 如果随后调用 Save 时, 应忽
略 FileName, 否则将产生运行时错误. 如果随后使用新的 FileName 调用 Save,
那么 Recordset 将保存到新的文件中, 但新文件和原始文件都是打开的.
==========================================================================*/
BOOL CAdoRecordSet::Save(LPCTSTR strFileName, PersistFormatEnum PersistFormat)
{
ASSERT(m_pRecordset != NULL);
ASSERT(IsOpen());
if (m_strFileName == strFileName)
{
strFileName = NULL;
}
else if(_taccess(strFileName, 0) != -1)
{
DeleteFile(strFileName);
m_strFileName = strFileName;
}
else
{
m_strFileName = strFileName;
}
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->Save(_bstr_t(strFileName), PersistFormat) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Save 发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
BOOL CAdoRecordSet::Load(LPCTSTR strFileName)
{
if (IsOpen()) Close();
try
{
return (m_pRecordset->Open(strFileName, "Provider=MSPersist;", adOpenForwardOnly, adLockOptimistic, adCmdFile) == S_OK);
}
catch (_com_error &e)
{
TRACE(_T("Warning: Load 发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
}
/*========================================================================
Name: 取消执行挂起的异步 Execute 或 Open 方法的调用.
-----------------------------------------------------
Remarks: 使用 Cancel 方法终止执行异步 Execute 或 Open 方法调用(即通
过 adAsyncConnect、adAsyncExecute 或 adAsyncFetch 参数调用的方法).
如果在试图终止的方法中没有使用 adAsyncExecute, 则 Cancel 将返回运行
时错误.
==========================================================================*/
BOOL CAdoRecordSet::Cancel()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->Cancel();
}
catch (_com_error e)
{
TRACE(_T("Warning: Cancel发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 关闭打开的对象及任何相关对象.
-----------------------------------------------------
Remarks: 使用 Close 方法可关闭 Recordset 对象以便释放所有关联的系统
资源. 关闭对象并非将它从内存中删除, 可以更改它的属性设置并且在此后
再次打开. 要将对象从内存中完全删除, 可将对象变量设置为 NULL.
如果正在立即更新模式下进行编辑, 调用Close方法将产生错误,应首先
调用 Update 或 CancelUpdat 方法. 如果在批更新期间关闭 Recordset 对
象, 则自上次 UpdateBatch 调用以来所做的修改将全部丢失.
如果使用 Clone 方法创建已打开的 Recordset 对象的副本, 关闭原始
Recordset或其副本将不影响任何其他副本.
==========================================================================*/
void CAdoRecordSet::Close()
{
try
{
if (m_pRecordset != NULL && m_pRecordset->State != adStateClosed)
{
if (GetEditMode() == adEditNone) CancelUpdate();
m_pRecordset->Close();
}
}
catch (const _com_error& e)
{
TRACE(_T("Warning: 关闭记录集发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
}
}
/*========================================================================
Name: 关闭连接并释放对象.
-----------------------------------------------------
Remarks: 关闭连接并释放CAdoRecordSet对象, 这样基本上从内容中完全清除了
CAdoRecordSet对象.
==========================================================================*/
void CAdoRecordSet::Release()
{
if (IsOpen()) Close();
m_pRecordset.Release();
m_pRecordset = NULL;
}
/*########################################################################
------------------------------------------------
记录集更新操作
------------------------------------------------
########################################################################*/
/*========================================================================
Remarks: 开始添加新的纪录.
==========================================================================*/
BOOL CAdoRecordSet::AddNew()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
if (m_pRecordset->AddNew() == S_OK)
{
return TRUE;
}
}
}
catch (_com_error e)
{
TRACE(_T("Warning: AddNew 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Remarks: 在调用 AddNew 等方法后, 调用此方法完成更新或修改.
==========================================================================*/
BOOL CAdoRecordSet::Update()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
if (m_pRecordset->Update() == S_OK)
{
return TRUE;
}
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Update 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
}
CancelUpdate();
return FALSE;
}
/*========================================================================
Name: 将所有挂起的批更新写入磁盘.
----------------------------------------------------------
Params: AffectRecords 可选, AffectEnum 值. 决定 UpdateBatch 方法
所影响的记录数目.可以为如下常量之一.
[常量] [说明]
------------------------------------
adAffectCurrent 只写入当前记录的挂起更改.
adAffectGroup 写入满足当前 Filter 属性设置的记录所发生的挂起
更改. 必须将 Filter 属性设置为某个有效的预定义常量才能使用该选项.
adAffectAll (默认值). 写入 Recordset 对象中所有记录的挂起
更改, 包括由于当前 Filter 属性设置而隐藏的任何记录.
adAffectAllChapters 写入所有子集的挂起更改.
----------------------------------------------------------
Remarks: 按批更新模式修改 Recordset 对象时, 使用 UpdateBatch 方法可
将 Recordset 对象中的所有更改传递到基本数据库.
如果 Recordset 对象支持批更新, 那么可以将一个或多个记录的多重更改缓存在
本地, 然后再调用 UpdateBatch 方法. 如果在调用 UpdateBatch 方法时正在编
辑当前记录或者添加新的记录, 那么在将批更新传送到提供者之前, ADO 将自动
调用 Update 方法保存对当前记录的所有挂起更改.
只能对键集或静态游标使用批更新.
==========================================================================*/
BOOL CAdoRecordSet::UpdateBatch(AffectEnum AffectRecords)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->UpdateBatch(AffectRecords) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: UpdateBatch 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 取消在调用 Update 方法前对当前记录或新记录所作的任何更改.
-----------------------------------------------------
Remarks: 使用 CancelUpdate 方法可取消对当前记录所作的任何更改或放弃
新添加的记录. 在调用 Update 方法后将无法撤消对当前记录或新记录所做的更
改, 除非更改是可以用 RollbackTrans 方法回卷的事务的一部分, 或者是可以
用 CancelBatch 方法取消的批更新的一部分.
如果在调用 CancelUpdate 方法时添加新记录, 则调用 AddNew 之前的当前
记录将再次成为当前记录.
如果尚未更改当前记录或添加新记录, 调用 CancelUpdate 方法将产生错误.
==========================================================================*/
BOOL CAdoRecordSet::CancelUpdate()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
if (GetEditMode() == adEditNone || m_pRecordset->CancelUpdate() == S_OK)
{
return TRUE;
}
}
}
catch (_com_error e)
{
TRACE(_T("Warning: CancelUpdate 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 取消挂起的批更新.
-----------------------------------------------------
Params: AffectRecords 可选的 AffectEnum 值, 决定CancelBatch 方法
所影响记录的数目, 可为下列常量之一:
[常量] [说明]
-------------------------------------------------
AdAffectCurrent 仅取消当前记录的挂起更新.
AdAffectGroup 对满足当前 Filter 属性设置的记录取消挂起更新.
使用该选项时,必须将 Filter 属性设置为合法的预
定义常量之一.
AdAffectAll 默认值.取消 Recordset 对象中所有记录的挂起更
新,包括由当前 Filter 属性设置所隐藏的任何记录.
==========================================================================*/
BOOL CAdoRecordSet::CancelBatch(AffectEnum AffectRecords)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->CancelBatch(AffectRecords) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: CancelBatch 发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Params: AffectRecords: AffectEnum 值, 确定 Delete 方法所影响的记
录数目, 该值可以是下列常量之一.
[常量] [说明 ]
-------------------------------------------------
AdAffectCurrent 默认. 仅删除当前记录.
AdAffectGroup 删除满足当前 Filter 属性设置的记录. 要使用该选
项, 必须将 Filter 属性设置为有效的预定义常量之一.
adAffectAll 删除所有记录.
adAffectAllChapters 删除所有子集记录.
==========================================================================*/
BOOL CAdoRecordSet::Delete(AffectEnum AffectRecords)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return (m_pRecordset->Delete(AffectRecords) == S_OK);
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Delete发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*########################################################################
------------------------------------------------
记录集导航操作
------------------------------------------------
########################################################################*/
/*========================================================================
Name: 将当前记录位置移动到 Recordse 中的第一个记录.
==========================================================================*/
BOOL CAdoRecordSet::MoveFirst()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->MoveFirst());
}
}
catch (_com_error e)
{
TRACE(_T("Warning: MoveFirst 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 将当前记录位置移动到 Recordset 中的最后一个记录.
-----------------------------------------------------
Remarks: Recordset 对象必须支持书签或向后光标移动; 否则调用该方法将
产生错误.
==========================================================================*/
BOOL CAdoRecordSet::MoveLast()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->MoveLast());
}
}
catch (_com_error e)
{
TRACE(_T("Warning: MoveLast 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 将当前记录位置向后移动一个记录(向记录集的顶部).
-----------------------------------------------------
Remarks: Recordset 对象必须支持书签或向后游标移动; 否则方法调用将产
生错误.如果首记录是当前记录并且调用 MovePrevious 方法, 则 ADO 将当前记
录设置在 Recordset (BOF为True) 的首记录之前. 而BOF属性为 True 时向后移
动将产生错误. 如果 Recordse 对象不支持书签或向后游标移动, 则 MovePrevious
方法将产生错误.
==========================================================================*/
BOOL CAdoRecordSet::MovePrevious()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->MovePrevious());
}
}
catch (_com_error e)
{
TRACE(_T("Warning: MovePrevious 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 将当前记录向前移动一个记录(向 Recordset 的底部).
-----------------------------------------------------
Remarks: 如果最后一个记录是当前记录并且调用 MoveNext 方法, 则 ADO 将
当前记录设置到 Recordset (EOF为 True)的尾记录之后. 当 EOF 属性已经为
True 时试图向前移动将产生错误.
==========================================================================*/
BOOL CAdoRecordSet::MoveNext()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->MoveNext());
}
}
catch (_com_error e)
{
TRACE(_T("Warning: MoveNext 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 移动 Recordset 对象中当前记录的位置.
----------------------------------------------------------
Params:
- lRecords 带符号长整型表达式, 指定当前记录位置移动的记录数.
- Start 可选, 字符串或变体型, 用于计算书签. 也可为下列
BookmarkEnum 值之一:
[常量] [说明]
--------------------------------
adBookmarkCurrent 默认. 从当前记录开始.
adBookmarkFirst 从首记录开始.
adBookmarkLast 从尾记录开始.
==========================================================================*/
BOOL CAdoRecordSet::Move(long lRecords, _variant_t Start)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return SUCCEEDED(m_pRecordset->Move(lRecords, _variant_t(Start)));
}
}
catch (_com_error e)
{
TRACE(_T("Warning: Move 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*########################################################################
------------------------------------------------
记录集属性
------------------------------------------------
########################################################################*/
/*========================================================================
Name: 取得记录集对象的状态(是打开状态还是关闭状态). 对异步方式执
行的 Recordset 对象, 则说明当前的对象状态是连接、执行还是获取状态.
-----------------------------------------------------
returns: 返回下列常量之一的长整型值.
[常量] [说明]
----------------------------------
adStateClosed 指示对象是关闭的.
adStateOpen 指示对象是打开的.
adStateConnecting 指示 Recordset 对象正在连接.
adStateExecuting 指示 Recordset 对象正在执行命令.
adStateFetching 指示 Recordset 对象的行正在被读取.
-----------------------------------------------------
Remarks: 可以随时使用 State 属性确定指定对象的当前状态. 该属性是只
读的. Recordset 对象的 State 属性可以是组合值. 例如: 如果正在执行语句,
该属性将是 adStateOpen 和 adStateExecuting 的组合值.
==========================================================================*/
long CAdoRecordSet::GetState()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetState();
}
catch (_com_error e)
{
TRACE(_T("Warning: GetState 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
return -1;
}
BOOL CAdoRecordSet::IsOpen()
{
try
{
return (m_pRecordset != NULL && (GetState() & adStateOpen));
}
catch (_com_error e)
{
TRACE(_T("Warning: IsOpen方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 指示有关批更新或其他大量操作的当前记录的状态.
-----------------------------------------------------
returns: 返回下列一个或多个 RecordStatusEnum 值之和.
[常量] [说明]
-------------------------------------------------
adRecOK 成功地更新记录.
adRecNew 记录是新建的.
adRecModified 记录被修改.
adRecDeleted 记录被删除.
adRecUnmodified 记录没有修改.
adRecInvalid 由于书签无效, 记录没有保存.
adRecMultipleChanges 由于影响多个记录, 因此记录未被保存.
adRecPendingChanges 由于记录引用挂起的插入, 因此未被保存.
adRecCanceled 由于操作被取消, 未保存记录.
adRecCantRelease 由于现有记录锁定, 没有保存新记录.
adRecConcurrencyViolation 由于开放式并发在使用中, 记录未被保存.
adRecIntegrityViolation 由于用户违反完整性约束, 记录未被保存.
adRecMaxChangesExceeded 由于存在过多挂起更改, 记录未被保存.
adRecObjectOpen 由于与打开的储存对象冲突, 记录未被保存.
adRecOutOfMemory 由于计算机内存不足, 记录未被保存.
adRecPermissionDenied 由于用户没有足够的权限, 记录未被保存.
adRecSchemaViolation 由于记录违反基本数据库的结构, 因此未被保存.
adRecDBDeleted 记录已经从数据源中删除.
-----------------------------------------------------
Remarks: 使用 Status 属性查看在批更新中被修改的记录有哪些更改被挂起.
也可使用 Status 属性查看大量操作时失败记录的状态. 例如, 调用 Recordset
对象的 Resync、UpdateBatch 或 CancelBatch 方法, 或者设置 Recordset 对象
的 Filter 属性为书签数组. 使用该属性, 可检查指定记录为何失败并将问题解
决.
==========================================================================*/
long CAdoRecordSet::GetStatus()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetStatus();
}
catch (_com_error e)
{
TRACE(_T("Warning: GetStatus 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
return -1;
}
/*========================================================================
Name: 获取当前记录集中记录数目
==========================================================================*/
long CAdoRecordSet::GetRecordCount()
{
ASSERT(m_pRecordset != NULL);
try
{
long count = m_pRecordset->GetRecordCount();
// 如果ado不支持此属性,则手工计算记录数目 --------
if (count < 0)
{
long pos = GetAbsolutePosition();
MoveFirst();
count = 0;
while (!IsEOF())
{
count++;
MoveNext();
}
SetAbsolutePosition(pos);
}
return count;
}
catch (_com_error e)
{
TRACE(_T("Warning: GetRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
/*========================================================================
Name: 获取当前记录集中字段数目
==========================================================================*/
long CAdoRecordSet::GetFieldsCount()
{
ASSERT(m_pRecordset != NULL);
try
{
return GetFields()->Count;
}
catch(_com_error e)
{
TRACE(_T("Warning: GetFieldsCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
/*========================================================================
Name: 指示通过查询返回 Recordset 的记录的最大数目.
==========================================================================*/
long CAdoRecordSet::GetMaxRecordCount()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetMaxRecords();
}
catch (_com_error e)
{
TRACE(_T("Warning: GetMaxRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
BOOL CAdoRecordSet::SetMaxRecordCount(long count)
{
ASSERT(m_pRecordset != NULL);
try
{
m_pRecordset->PutMaxRecords(count);
return TRUE;
}
catch (_com_error e)
{
TRACE(_T("Warning: GetMaxRecordCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
}
/*========================================================================
Name: 指针是否在在记录集头
==========================================================================*/
BOOL CAdoRecordSet::IsBOF()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->adoBOF;
}
catch(_com_error e)
{
TRACE(_T("Warning: IsBOF 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return FALSE;
}
/*========================================================================
Name: 指针是否在在记录集尾
==========================================================================*/
BOOL CAdoRecordSet::IsEOF()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->adoEOF;
}
catch (_com_error e)
{
TRACE(_T("Warning: IsEOF 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
}
EditModeEnum CAdoRecordSet::GetEditMode()
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL)
{
return m_pRecordset->GetEditMode();
}
}
catch (_com_error e)
{
TRACE(_T("Warning: UpdateBatch 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return adEditNone;
}
return adEditNone;
}
long CAdoRecordSet::GetPageCount()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetPageCount();
}
catch (_com_error &e)
{
TRACE(_T("Warning: GetPageCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
BOOL CAdoRecordSet::SetCacheSize(const long &lCacheSize)
{
ASSERT(m_pRecordset != NULL);
try
{
if (m_pRecordset != NULL && !(GetState() & adStateExecuting))
{
m_pRecordset->PutCacheSize(lCacheSize);
}
}
catch (const _com_error& e)
{
TRACE(_T("Warning: SetCacheSize方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
return TRUE;
}
long CAdoRecordSet::GetPageSize()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetPageSize();
}
catch (_com_error &e)
{
TRACE(_T("Warning: GetPageCount 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
/*========================================================================
name: 指定当前记录所在的页.
----------------------------------------------------------
returns: 置或返回从 1 到 Recordset 对象 (PageCount) 所含页数的长整型
值,或者返回以下常量.
[常量] [说明]
---------------------------------
adPosUnknown Recordset 为空,当前位置未知,或者提供者不支持 AbsolutePage 属性.
adPosBOF 当前记录指针位于 BOF(即 BOF 属性为 True).
adPosEOF 当前记录指针位于 EOF(即 EOF 属性为 True).
==========================================================================*/
BOOL CAdoRecordSet::SetAbsolutePage(int nPage)
{
ASSERT(m_pRecordset != NULL);
try
{
m_pRecordset->PutAbsolutePage((enum PositionEnum)nPage);
return TRUE;
}
catch(_com_error &e)
{
TRACE(_T("Warning: SetAbsolutePage 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return FALSE;
}
}
long CAdoRecordSet::GetAbsolutePage()
{
ASSERT(m_pRecordset != NULL);
try
{
return m_pRecordset->GetAbsolutePage();
}
catch(_com_error &e)
{
TRACE(_T("Warning: GetAbsolutePage 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
return -1;
}
}
/*========================================================================
name: 指定 Recordset 对象当前记录的序号位置.
----------------------------------------------------------
returns: 设置或返回从 1 到 Recordset 对象 (PageCount) 所含页数的长整
型值,或者返回以下常量.
[常量] [说明]
---------------------------------
adPosUnknown Recordset 为空,当前位置未知,或者提供者不支持 AbsolutePage 属性.
adPosBOF 当前记录指针位于 BOF(即 BOF 属性为 True).
adPosEOF 当前记录指针位于 EOF(即 EOF 属性为 True).