QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3523|回复: 0
打印 上一主题 下一主题

[转帖]在Visual C++中用ADO进行数据库编程(中)

[复制链接]
字体大小: 正常 放大
god        

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
: B) U6 C# ~$ b# C2 i- ]* y: o. ?
2 p9 P" S# F' S0 X% c0 |& B  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
0 ]: `* q' a; I, i9 U1 L并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
; H6 g" g, H% V( q; u0 ]SQL命令的执行可以采用多种形式,下面我们一进行阐述。2 O) g. E" i5 V1 \0 I: i  W

  K& ~7 i$ U3 F  N  (1)利用Connection对象的Execute方法执行SQL命令
# @2 |9 c; N1 A, w0 w! d8 [' a1 I* y, N7 _3 W, S- b0 C- r
  Execute方法的原型如下所示:
, H4 j7 T( Z2 a( p. A5 U! @2 ]2 h0 {/ p  u$ O
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 6 V' G5 J: M: P& N& s

& c$ V7 p# w: f, j0 {  @其中CommandText是命令字串,通常是SQL命令。/ l) Q7 t0 ?7 r
参数RecordsAffected是操作完成后所影响的行数, % ?5 V' m! o% L3 ?: }8 j
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
4 V8 {2 N6 r9 S- VadCmdText:表明CommandText是文本命令6 u8 `3 \; v: ?' L5 E: L
adCmdTable:表明CommandText是一个表名
$ B: T/ F6 v- Q2 H# a  S) ^adCmdProc:表明CommandText是一个存储过程
- s' i6 z# i: @adCmdUnknown:未知
; [4 c' n# K% t- d
0 R8 R7 L5 f4 t4 j! \Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
+ f/ D$ V8 F/ X9 h" o9 u- N/ Q_variant_t RecordsAffected;
3 `. U1 ?) R: B3 e& r; [8 v# N$ X( `3 v* }///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday5 z0 T; n5 {+ S# o2 i/ O/ i; n
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
. o+ R  H0 ?5 }3 R, F2 O" u&RecordsAffected,
, A( S' X" b% C) G2 l3 YadCmdText);) L/ S' L0 Q2 T  z

' h* P2 P* ?# {: {; }, D///往表格里面添加记录; l7 Y" D$ g8 P8 I! j, v
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
, o" I3 R1 P! Y/ V" q9 i% q' V
+ {( n) h8 w! F$ t" J! K///将所有记录old字段的值加一
# A* p/ F3 G' F) |; V5 jm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);# X8 H& h" S+ R8 X- K

4 g" P2 i+ K* r3 z///执行SQL统计命令得到包含记录条数的记录集
  a* u7 U. Z$ V* c2 K* ?' ?m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
/ i; p) j  a( X6 {* _: t; B_variant_t vIndex = (long)0;
& d: K0 ^- t4 e! h_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量) R* M" N# r/ P1 Y% c) _
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
$ _$ y8 m1 b; a9 Cm_pRecordset->Close();///关闭记录集
2 f1 X( Y: ]  m7 y+ s# s  S  }CString message;" E0 l; q5 P& h$ E0 \
message.format("共有%d条记录",vCount.lVal);3 V0 z0 _) S4 X; ^  s
AfxMessageBox(message);///显示当前记录条数) |: v. |: l% e% p- c6 N
# I( o" q0 m" a0 _5 [. ]
(2)利用Command对象来执行SQL命令
5 D2 w- n0 R: S* a% _( }( ~9 q, r) J+ `& _
_CommandPtr m_pCommand;
  S! ^7 F1 _/ hm_pCommand.CreateInstance("ADODB.Command");8 T0 k4 a: r" b
_variant_t vNULL;9 o' p( I5 {3 b* ?
vNULL.vt = VT_ERROR;
" s0 o$ M8 [. r/ g2 MvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
8 I3 @$ R" r- a2 F6 N( i- \% Sm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
4 G) S$ F( R7 l; O0 u# @' im_pCommand->CommandText = "SELECT * FROM users";///命令字串
3 x- W% Z0 C& P1 w, Am_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
, f+ U" m; K, G: H3 H2 k% ?
! u$ o; Q9 W! |$ @! T- B  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 0 F1 ^$ I9 x3 Z! ~2 [% i" l
3 Q( O2 b- t: M
  (3)直接用Recordset对象进行查询取得记录集
" ~) w6 g! A8 z. w
' e( D: j8 p9 n4 V6 w  实例——
! q5 \) e9 A& _. [, a' K+ H6 q8 D% y! Q) l+ ~: |
void CGmsaDlg::OnDBSelect() 3 I0 n, H4 ]" h. Q2 v
{
% x) e% q( f1 k! U: x// TOD Add your control notification handler code here* u8 `- D' ?* v  {1 a7 ~0 P" [7 v
_RecordsetPtr Rs1; //定义Recordset对象
" X' m2 g  ]' L; O1 @0 |_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串- Q: e; F* x' @
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句* s$ v  c/ N6 b6 G$ I, B
::CoInitialize(NULL); //初始化Rs1对象4 g4 |4 q) Z( u+ ^
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
3 |' N! S5 a2 I3 |" e//省略对返回值hr的判断 + Q1 D; A! x- P6 E
Rs1->Open( Source,) a" F2 a; s' u* t- L8 _5 q
Connect,+ K0 F: F+ x4 i" ^+ I% e3 f
adOpenForwardOnly,
: L- f0 r& L# b  e* n# L  ~; q# padLockReadOnly,3 B9 e" p' _# c
-1 );
+ X' w. ~* }" R; A) ?8 v2 z_variant_t temp=Rs1->GetCollect(_variant_t((long)0));  _0 f2 f5 l) G  P. w
CString strTemp=(char* )(_bstr_t)temp;
0 R% e: _( u8 ^! C! B# Z: cMessageBox("OK!"+strTemp);; \& @8 G; h8 D
}/ C5 t* Z* `4 i% o0 D2 J
1 l! r% M$ Q* H7 @2 P2 k( U
例如
9 I- O" B' m! Xm_pRecordset->Open("SELECT * FROM users",$ {0 W3 `8 Q7 a! b: ^* ^/ P1 u0 p2 N
_variant_t((IDispatch *)m_pConnection,true),
# k! M' U$ s! TadOpenStatic,
! A, H2 Z+ S) S0 G+ _! D' uadLockOptimistic,8 _0 K; M! H& O& J8 C
adCmdText);
' M& A9 ^* |9 M* A9 x( ^  J1 \. x. ^& O
Open方法的原型是这样的:+ ~: M4 B% {1 g# ^
HRESULT Recordset15::Open ( const _variant_t & Source,
5 y, Q  |5 \; W9 N; Uconst _variant_t & ActiveConnection,
5 L" C  Q! C$ P5 u* ^) P5 kenum CursorTypeEnum CursorType,
6 ^5 _& ~0 H6 V9 }6 X. v0 Cenum LockTypeEnum LockType,
) d, |0 `$ g! z* J: Y7 `4 Along Options ) " g8 e& x4 O) e" @- k
$ y- k& i& V, d" Y) w* i( i6 Q
其中:
2 ]- k5 D" ]; U5 X) ~0 s) ]% w' X: }! d6 }' e
①Source是数据查询字符串) I/ ]2 N6 X; y5 B% {4 C" [
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ' ~2 H0 e% e% `5 e( X9 P4 C; m
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
% |' _* ~8 Z8 Q$ x& P. [- c$ W9 v1 C* G+ D* |' G
enum CursorTypeEnum0 t, e. V- ~8 Z$ h" A
{5 C4 @4 L  T1 k$ _7 Q5 R, F, N- a
adOpenUnspecified = -1,///不作特别指定
! I( ?& N  w2 q3 r/ dadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用1 z. _+ h9 R& o( w
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
) k* k: ?; Y6 I& _+ x$ `% ]% e' d
/ Q0 p$ G4 _) z" j% e: j" J" _adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。2 h6 C) m4 [0 g
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
; Y& t0 k2 Q7 |7 U$ _};
) Y, O- Q, W, d/ X④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:+ k0 E; c  q+ b: X4 f1 ^
7 E( t5 v. F; C
enum LockTypeEnum
0 n% O' I4 f# j/ V* x0 R{, O$ m9 A' d( r$ ]3 G$ F
adLockUnspecified = -1,///未指定
/ S- ~. E1 c7 Y$ {8 N6 o7 radLockReadOnly = 1,///只读记录集9 s: a6 r+ u2 X: \
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制# X( F1 ~0 C- e# [; T  @9 V: G
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
0 U- T* s2 l+ k8 c8 `3 QadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。: x4 M2 P7 c- D$ y
}; 0 E+ ?9 E# x3 h6 j: \
& K, X. S' s1 e: G4 C6 S: \
⑤Options可以取如下值之一:6 i4 t$ [! Y2 B2 `
adCmdText:表明CommandText是文本命令
, v0 e' [. {* C; g2 XadCmdTable:表明CommandText是一个表名% w0 q! X; k$ H% S
adCmdProc:表明CommandText是一个存储过程
6 Q: @( r1 U% G6 j5 _; e8 QadCmdUnknown:未知
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
如果我没给你翅膀,你要学会用理想去飞翔!!!
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-6-3 14:39 , Processed in 0.415463 second(s), 51 queries .

回顶部