QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集4 @6 d1 s7 h2 m! ?' ~1 n) ~

8 Z, K  w9 e, g" W! V3 X  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;' s- w5 j4 E' R, k
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
$ v, Z# [3 p2 d1 u& |* `SQL命令的执行可以采用多种形式,下面我们一进行阐述。
. h1 ~( Q- X3 d% ^3 o! d$ r$ x3 ?. _5 z* k# ~5 ?- m
  (1)利用Connection对象的Execute方法执行SQL命令7 }+ C+ C, C/ m) m, y' {

2 f+ {1 P% k- u# R2 f" ^  Execute方法的原型如下所示:; H* |; ]! z7 x) Y  d! A
4 g/ Q. b" _- C' T, x0 A$ R
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 1 A, V, z* B* |0 o; k1 T
  F/ f, S$ e* r+ i, w! F* T
其中CommandText是命令字串,通常是SQL命令。
# ]5 Z6 |% R! H* U( a! i8 g参数RecordsAffected是操作完成后所影响的行数,
- E6 J1 ]4 q% ?* K4 m0 [4 d& M参数Options表示CommandText中内容的类型,Options可以取如下值之一:
6 ^, L' u, ^  Z) u$ V( padCmdText:表明CommandText是文本命令
" e4 g& e0 C+ k/ m, M5 radCmdTable:表明CommandText是一个表名
4 w/ w/ g: Q# i& ladCmdProc:表明CommandText是一个存储过程
0 P" `4 ]4 G' h, `( h# a% u7 MadCmdUnknown:未知' l8 N8 i" I( I. R( L
& \9 z  B( C, S( _: w1 m& Y
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
, X0 p' u$ J0 ~$ B_variant_t RecordsAffected;6 F" K; X* z  }! `0 ^7 Y, A# H0 y
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday/ m/ M* F- T6 H
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
( g6 _4 |& E: Y& w4 u4 `2 L&RecordsAffected,# {" D* Z; z  L+ p4 X" A+ l2 X8 L
adCmdText);
7 o' d9 p, V. ~) `; C3 s! r) S8 }: n' j/ X7 [9 p' ^0 _
///往表格里面添加记录. t& P/ z/ m4 F7 m9 `
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);0 ]& Z: l/ @* v; W, s
, S( a/ [# I1 Y3 L2 z* Z
///将所有记录old字段的值加一6 i( }9 [* n. N3 z  K6 J+ v
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
# H4 t' Q' m/ L( C
9 I3 i3 U! J: ]4 x% ?8 _///执行SQL统计命令得到包含记录条数的记录集7 ^4 R& }4 ]. X3 e
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);" q- e( c  y) c' C1 i7 D
_variant_t vIndex = (long)0;1 I3 e' L1 y+ P+ i3 ?! X
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量! n  m7 M, ], T6 @2 k
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));1 t- _2 U$ m' u
m_pRecordset->Close();///关闭记录集: E3 E1 w3 F* n3 m6 E" o" O& d+ G
CString message;2 u1 b& u' i0 W' i0 `- b3 C
message.format("共有%d条记录",vCount.lVal);$ U4 w" z' O! h( W8 ?* a
AfxMessageBox(message);///显示当前记录条数/ n" o; ^  N9 j
: R- C6 y1 p6 B2 ]1 L0 r7 _
(2)利用Command对象来执行SQL命令 % d# a0 T4 p; r9 a4 L$ s

" w& i/ H( _- t_CommandPtr m_pCommand;
$ Y  K0 S% k+ ?! ^, l! z$ _$ f: w- M; ^m_pCommand.CreateInstance("ADODB.Command");
+ x* L* K8 Q! |1 H% a_variant_t vNULL;2 A' y; _. a. P
vNULL.vt = VT_ERROR;. e$ d$ @4 n$ l9 ^( ]
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
  B  M7 _9 S; h* ?& _* ]- Fm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它  R; S. d& g, @+ ]3 B1 h
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
6 J8 r: r; p3 w" D1 Y. Qm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集! T2 v5 g. o# m) F  B) b

5 P6 A5 c' c- Q! y% k3 C  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
! ~( C2 [* I( A' P: O& _* `% B' z$ V# o/ N0 y4 P: `3 v0 K
  (3)直接用Recordset对象进行查询取得记录集( f3 h1 j+ u& U1 }. @
; ^  Y9 }3 o7 m# @" f
  实例—— - c1 w+ J* i, [7 z7 e
8 G9 H8 A/ p+ i( S
void CGmsaDlg::OnDBSelect()
5 [3 u/ M/ B& M{
# P' C( Z- z# P// TOD Add your control notification handler code here/ i8 s1 w# o* C
_RecordsetPtr Rs1; //定义Recordset对象' i0 e. b; S- N8 C+ t2 @$ f0 ]
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
4 C* r) P1 `- U% Y_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
' }, g! t; `1 J::CoInitialize(NULL); //初始化Rs1对象
9 z0 m. Y7 ?+ t: E; m2 }HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );+ e6 M( H- w+ ]* K7 y
//省略对返回值hr的判断 7 @7 W" E, [; S) J! T& D
Rs1->Open( Source,
8 q5 H1 n5 j/ @1 D" z0 e! ?3 }Connect,1 E2 C' y1 w# \) q. z: w
adOpenForwardOnly,
( P7 H$ n) _" |  q' r6 l, NadLockReadOnly,
! m; d- C3 p: W$ y4 N. b-1 );
# `3 M* y" _3 U, x# i3 E+ {_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
: k7 S, N- A: ~* T0 q, iCString strTemp=(char* )(_bstr_t)temp;
( ?! P( G9 f* FMessageBox("OK!"+strTemp);
' B3 x. [% ?/ d}
; T, b: p- T, Q4 S' [# D8 g( ^# M9 [$ K& ^/ ]! F2 ?
例如 7 m# E* Z7 P. H9 ]+ X! g
m_pRecordset->Open("SELECT * FROM users",3 S: w/ t. [; K' y
_variant_t((IDispatch *)m_pConnection,true),) V; n+ n3 F. c" W" C2 J$ T
adOpenStatic,
$ }! G5 Z8 ^2 B3 g! H1 J  _adLockOptimistic,
6 g* I% C2 Q7 x: Y! B7 m+ q' y( kadCmdText);5 h4 ?6 h9 Z2 j5 A5 Q, j4 B, k

3 R) t$ j- j+ ~! JOpen方法的原型是这样的:
8 R& p1 P' _5 f  P8 {HRESULT Recordset15::Open ( const _variant_t & Source, # O3 |& G' j. X: j
const _variant_t & ActiveConnection, / f" j) Y* Z- S& @7 |  v0 H
enum CursorTypeEnum CursorType,
8 |/ j4 }: ]2 O9 c/ x, v- {+ }enum LockTypeEnum LockType,
" ]4 F/ h: O* ~+ ?+ ulong Options ) ; m/ H+ r8 g, i4 E- K; y4 P$ ?( @
" l' p1 `% s- p$ \; m
其中:+ P; r; J' X4 D2 b5 ^. k/ m

- e9 Q. X! o  |" p①Source是数据查询字符串( S( L8 J/ q) O" R2 A
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
* N. l6 z1 M1 ~0 C③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:! b" J+ Z. N  o0 [1 R0 m

7 B/ Q7 |) k4 X: W# henum CursorTypeEnum
7 P0 {: |7 W3 b5 V/ V* U; \8 ]{$ m- Z; \: c8 c+ t, s4 H2 q
adOpenUnspecified = -1,///不作特别指定
$ ]4 I2 f% I  s! x/ T; |+ WadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
5 y  @' X' v0 I: _* |2 IadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。8 k# r9 w- ]: r" e* N
/ k& T: M" d9 I; ]; ^
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。6 {6 }3 N' W( I2 y
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。+ W, d4 l9 {9 b5 U3 i! \" x  X
};2 J/ s' A9 T0 C% T: x# u
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:/ Q# I/ R6 F4 l* H5 f
' P& h" f# [8 v+ \* @
enum LockTypeEnum7 Y2 r  T/ N  p4 U: N
{7 W+ ?4 `+ _8 h  e+ G. x% H
adLockUnspecified = -1,///未指定) i. w6 o7 T3 V4 C
adLockReadOnly = 1,///只读记录集) J0 H7 o! \) D# H0 D2 A
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制; {4 O" ~+ }  [: m. |% y
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
: @% L+ y- S3 yadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。3 Q, {' k. O1 E0 ^- L" |$ G' K
};
/ w9 o% m* ~( ]2 T. |% T
# Y" R3 V/ R& z! ?, r8 p⑤Options可以取如下值之一:
  L6 g+ g: N1 g0 XadCmdText:表明CommandText是文本命令
7 G# f! K9 Z" R# G% NadCmdTable:表明CommandText是一个表名! k# x9 O9 p3 O3 b  u  ^  `
adCmdProc:表明CommandText是一个存储过程
6 Y6 o9 i5 M0 O5 [3 R( {+ |adCmdUnknown:未知
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 16:21 , Processed in 0.434111 second(s), 51 queries .

回顶部