QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集( F6 @2 K* W1 r6 [& [- n+ f
& M" K9 _, F& C4 b/ Y8 R5 v6 t
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;* B+ Y  t% P( j; C  f' D
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
& g  M3 n. r/ l5 c5 W7 d( _( I: bSQL命令的执行可以采用多种形式,下面我们一进行阐述。! K; W3 d5 u7 U$ M" f
, K) i9 r* P7 ]  W5 A+ C
  (1)利用Connection对象的Execute方法执行SQL命令
0 J& |! S: f, e) j$ A; b2 \: |0 H! E, g# S" z5 L
  Execute方法的原型如下所示:  |$ w# U' z* O- V3 s4 g: C9 S

: X1 I: z4 _3 \4 i_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
# T- B' l9 B1 X( I' Z% Z# G" L4 n: Z
6 `- b5 j4 z6 s$ |# d6 ^9 A其中CommandText是命令字串,通常是SQL命令。
: g  b0 |' Q2 c, f( i& P参数RecordsAffected是操作完成后所影响的行数,
/ ^2 @- x& ~7 `% y$ N" M参数Options表示CommandText中内容的类型,Options可以取如下值之一:$ {! j) N) Q: j3 n$ Z7 h: l& b2 h
adCmdText:表明CommandText是文本命令" [, q) m# z3 h. J. F7 U/ I( V
adCmdTable:表明CommandText是一个表名
# T6 E) N) o3 _1 H' m/ j1 vadCmdProc:表明CommandText是一个存储过程8 v0 Y" }6 T0 [" i" F8 t" V; O1 ]
adCmdUnknown:未知# e4 p/ L. u' T' K
  G: T" m, c" o$ y$ C
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 - Y" P' Z3 \/ s) S- l% v6 h
_variant_t RecordsAffected;+ b( Q8 |2 G7 ?6 G" Z# X4 k
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday3 u9 \% ?: F+ ^) \+ b9 H7 ^
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
, F$ Q& r) O9 y2 a& N6 G* C" y5 Z&RecordsAffected,
1 t4 f' H: s) uadCmdText);5 E4 x4 G2 Y0 t4 r7 q

6 B+ ^/ `, C$ k. s; z$ u; A///往表格里面添加记录
2 P1 v3 d  g) g7 ]1 g6 O) Rm_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);1 p4 Y; V+ M' K- D# _
  T, a( {# {8 g0 P; p' o
///将所有记录old字段的值加一" E/ z. W9 T4 W% @- e
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);. B) Y% V) W& |. ~0 D) @. i3 x

3 {- c, _" G/ i2 }+ ]///执行SQL统计命令得到包含记录条数的记录集4 Q% G, F* u( a' f$ T% {
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);3 N* X0 [7 F) n) z$ j% U
_variant_t vIndex = (long)0;
3 v  b2 R$ o3 L& p+ D, S  X_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量4 y: o; M, l* B  g2 Z
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
) S! j) O! L3 q/ Q: X- Tm_pRecordset->Close();///关闭记录集# @. c- m: i( H
CString message;
& O8 a. K, x5 g! s% f3 w0 @: q; ^6 Gmessage.format("共有%d条记录",vCount.lVal);
8 Y* F2 d3 x0 XAfxMessageBox(message);///显示当前记录条数
7 Y' r- Q6 {" L
/ \1 B7 c. g3 w6 u6 K/ z: P(2)利用Command对象来执行SQL命令
. v% M7 i& w5 R1 b) I
$ M6 [& J1 {; I. U' n; __CommandPtr m_pCommand;8 g, Q3 j/ R' W$ C( b  u+ \: L2 N( ?
m_pCommand.CreateInstance("ADODB.Command");; p" H7 e3 C7 f3 `% t% Q/ z
_variant_t vNULL;
: ~  P9 V7 f- |: b! ^vNULL.vt = VT_ERROR;" Y3 Y' ^' J$ Q6 x' A* `
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
8 l1 @5 k" q$ q- k3 zm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
: Z5 w" f8 |& q" }m_pCommand->CommandText = "SELECT * FROM users";///命令字串
/ z% i$ w: N8 P+ r6 @0 r9 am_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集# j7 N+ V$ B- R7 Z

5 L0 a( j2 Z% I& ?  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 - Q6 H/ v) ?# K# y& g
& ^& ]% P  F0 u
  (3)直接用Recordset对象进行查询取得记录集  ~/ X0 L; ~5 C; G$ G9 `, v# q2 \
! \" Y. H0 |6 D, C( L/ ^
  实例—— . u0 h3 z4 P  X0 y$ P* z( m% `
6 Z+ o+ x* i4 n
void CGmsaDlg::OnDBSelect()
/ B; p4 i( h/ g{
$ g1 {1 c1 A0 U+ c// TOD Add your control notification handler code here
3 h. t# d: {& E_RecordsetPtr Rs1; //定义Recordset对象/ f  M( _" a% f  ^
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
( H" j! K$ J: f2 f$ C_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
$ f) o7 ~  X) g( J6 W::CoInitialize(NULL); //初始化Rs1对象
% e: ?  E! B- y' ~- K5 w9 [' vHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );0 C& N+ r/ l/ x1 w
//省略对返回值hr的判断
! ]3 n/ F: w; {2 @8 WRs1->Open( Source,7 Y4 z+ ]( D1 {  D5 `- r  t
Connect,2 `: N. A7 k* p% d( y
adOpenForwardOnly,
0 E! `; f4 X9 i7 w! [adLockReadOnly,
2 B. A4 L+ o6 n1 v/ \; t8 D+ F5 _-1 );
- ^2 y5 N' b" V0 b% r: e! T_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
, ^: o& a6 q* o9 bCString strTemp=(char* )(_bstr_t)temp;
: @* l' J+ s* P% v+ rMessageBox("OK!"+strTemp);1 J/ Q" Z- A: Q( W
}
; X: k3 Q4 i4 R% ]" w9 I$ \" s2 @7 W* ]
例如
& K8 O5 U1 l3 D8 R; [) f/ xm_pRecordset->Open("SELECT * FROM users",$ f. r) R0 O$ b, z
_variant_t((IDispatch *)m_pConnection,true)," i7 W. ~9 j: @8 X$ e! s6 Y+ x
adOpenStatic,
; S0 Z  S3 I+ z# ]; v5 |adLockOptimistic,
0 r" L9 O. B2 A$ M% ^adCmdText);6 m. c+ T  c/ O4 n; V( s) s# f

+ s' N& T, m* ~* OOpen方法的原型是这样的:4 o* S9 P- V8 L
HRESULT Recordset15::Open ( const _variant_t & Source,
& P% z2 X8 ]& d. Z& z5 Jconst _variant_t & ActiveConnection,
' f- J& R# p7 ^# u+ P4 v' L# genum CursorTypeEnum CursorType, ! Z; ^: j! k2 B+ T% e5 L2 [
enum LockTypeEnum LockType,
$ E- K; C5 S2 s$ i  P- }( Ilong Options )
8 G0 P  }) l/ u) R7 }  y0 s) G7 P; `. d0 u& s! @
其中:" A) B$ S! p9 u; |

: Y0 h; m2 a* X; u, g+ l! d①Source是数据查询字符串$ k2 Y' W4 c% ?" J
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ; @3 U9 a' Y% P) n
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
! z( w! C0 r, g- j1 z; w( `  o. {( B. G" B' A% a* E5 r; x# k
enum CursorTypeEnum2 Q0 x; e! ]; L5 ~  ?# @3 `7 K
{
2 S0 `* F( \2 @8 U  r! J" \4 ?adOpenUnspecified = -1,///不作特别指定
1 U2 Z' Z/ }- i: CadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
5 E% z+ _# p) gadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
; i9 i( }6 |& f; F& k9 E$ _3 {6 T1 _. s# B, V5 s! }9 y4 A( S4 U
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。& s  Y$ r" j! ?3 y0 g+ |7 O! w
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
1 i7 H, F9 O- B3 m4 u};
% h+ ?, `& M# g④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
- Y5 z% K( I- y% Y% U% t( ]0 Z2 h2 D' j- x. ~& v7 c& _2 p
enum LockTypeEnum+ M6 g* G2 y2 B- w+ _$ Z' ?
{
, ~! N" S% Q4 B, hadLockUnspecified = -1,///未指定, \2 ?5 Q0 D8 J4 V) U
adLockReadOnly = 1,///只读记录集( V+ ^* I6 ?! m( O" j
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制% q* V+ @& F) ^' C+ f& ?
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
4 L5 d1 s! M& P) a) ]% K7 ~+ wadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
0 l" l7 l3 f6 j1 `};
7 |/ R- k! L% I; q- i! O. V$ S  T) {( q/ n
⑤Options可以取如下值之一:8 y5 {, |1 m) K2 K5 f4 I
adCmdText:表明CommandText是文本命令  b; u$ w- [& p4 B& R* @! {
adCmdTable:表明CommandText是一个表名# P* {# s3 h; Q9 _3 M2 [/ p+ p' a
adCmdProc:表明CommandText是一个存储过程
+ O  _! C( d+ |# E. CadCmdUnknown:未知
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-7-20 00:53 , Processed in 0.383659 second(s), 52 queries .

回顶部