QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
5 v* a1 g6 l4 s1 v. x' }% v: S1 `! _1 y! U9 R
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
& K5 D+ W: a) |% Z$ L# F并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");0 s4 [1 e2 x) L6 w/ y
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
& ^$ [# v/ N$ R; P6 G* q& q( L0 i5 s9 {- T
  (1)利用Connection对象的Execute方法执行SQL命令4 |# g$ X+ f# t: e" ^
# v9 E, x( R% ?
  Execute方法的原型如下所示:
* ?2 V1 z4 T/ d: U4 R4 U
. _- b# l( g' ]_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
1 K9 p. ~# L/ m* F
/ K) i" f4 \# K' r8 d其中CommandText是命令字串,通常是SQL命令。! |/ A& x8 I# r# H: K
参数RecordsAffected是操作完成后所影响的行数, 0 S, r. w+ J# |1 r' t
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
3 T5 d  ^* u& o, p+ T% madCmdText:表明CommandText是文本命令
4 o' F2 H! P9 _" e: `adCmdTable:表明CommandText是一个表名! W; _* p0 c# q4 D
adCmdProc:表明CommandText是一个存储过程
' ~) W  c) U0 `adCmdUnknown:未知9 T# t$ ^* Z# E: t3 m' B4 c
7 T: v% a3 r* i9 c1 O+ H, t
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 8 M: ^0 j, E3 l8 T
_variant_t RecordsAffected;) _* p. a! }- i3 X
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
. Q2 @+ y1 H' a4 B$ p! F1 km_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",& h  Y- k3 _1 N- i6 T: i" m
&RecordsAffected,/ S4 X% O8 F5 _8 S! s
adCmdText);/ C' ?4 I% y8 J# e0 a. N& e0 ?
! c2 [3 W; F5 L/ q2 k5 K
///往表格里面添加记录, q" c0 C# q! f! p( E
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
  o0 ?& A# Z( k, W! ]* L6 o& W4 t" f: `* S
///将所有记录old字段的值加一) g3 \! y+ F# I9 \- }
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
' c7 i# c: e$ j' B' p0 G5 T/ K9 F4 V- M' G8 o5 z7 T6 e$ n
///执行SQL统计命令得到包含记录条数的记录集
# h& Z! ]% V* X+ t( W  o( w9 Zm_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);" m# a4 r( f0 H5 Z) h
_variant_t vIndex = (long)0;
. }7 {( t1 D4 w# r_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
$ ?5 W5 y4 y( o, L3 i3 q" C. N上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));) v+ n+ `: B9 c9 {: q8 s2 Q" y) N' w8 U
m_pRecordset->Close();///关闭记录集
5 A. w4 t5 u+ E: R& k7 NCString message;& s. ], K/ d2 D& j( y: S6 a. a, i
message.format("共有%d条记录",vCount.lVal);
# ^, i! |9 A& RAfxMessageBox(message);///显示当前记录条数5 T7 T7 U+ ~0 p0 h

) r6 z. U" [! \* J: h+ ^(2)利用Command对象来执行SQL命令
1 A" i  B( v- m$ l" y4 C
% {0 h$ ~! s4 Q2 y_CommandPtr m_pCommand;( o# K8 P6 Y4 L* @. V/ h- A$ ^, |# J' c8 d
m_pCommand.CreateInstance("ADODB.Command");
5 y: \9 @5 c3 H_variant_t vNULL;
, F- u* \2 m, \vNULL.vt = VT_ERROR;( y# P( l9 y% c. P
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数0 D0 A2 Y4 n$ ^3 `4 a, e
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它- d5 r6 }! L, I8 s
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
/ x5 c' E8 X9 k7 ^m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集2 ^4 U+ r/ c3 e4 s2 d) ^

& Q0 g7 e, F$ x% w- f% k" w( p- }  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
2 n4 F8 y# {; g7 ^* H
: l) M% ^; V9 y- a! O  (3)直接用Recordset对象进行查询取得记录集
, ^2 c: M0 I9 r  e5 t2 [' \' Y
$ W6 f& s5 j4 H9 ~3 t  实例——
1 G$ Q6 l% p$ x6 s  V0 x+ m0 @. v( {9 M0 |: d" @0 h. E
void CGmsaDlg::OnDBSelect() ) S5 `1 L. b+ |* }6 Y" f
{9 u! a# P$ F/ A# }3 O3 P$ E2 Q  F; N
// TOD Add your control notification handler code here
4 G, p; z- L' n2 r' T& I9 H_RecordsetPtr Rs1; //定义Recordset对象
' x* ], u" P" \9 M* ^- B9 @_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
% X- h! q; r! P9 w- [_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
3 H9 k, @" d( e& i4 {' D::CoInitialize(NULL); //初始化Rs1对象( \* @* c6 U. P. m: @
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
4 F$ s8 b0 s1 q/ ?4 h% }//省略对返回值hr的判断
+ I" i9 J+ F: U, n3 t" \' JRs1->Open( Source,
: c+ m* |  J3 a+ yConnect,
% u2 i& S4 h9 o3 Y* MadOpenForwardOnly,$ K/ J! {' s0 q. I. O: [: T3 p
adLockReadOnly,
; o' h/ f8 K9 a. E/ t-1 ); # ]) X2 o. y- [
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));/ x1 N; `6 N9 e9 Q
CString strTemp=(char* )(_bstr_t)temp;* S: t( B$ a  u0 B9 W3 R
MessageBox("OK!"+strTemp);% \. O+ ^- C, H1 ]
}8 |% u/ b  g# g. _1 H8 ?
$ m0 f+ @% c& H$ ~( e
例如
& |, U$ E  u8 v9 V5 Em_pRecordset->Open("SELECT * FROM users",
5 a) J9 H3 R& ^1 L6 D_variant_t((IDispatch *)m_pConnection,true),
% [6 v2 c3 O8 I- ~, m7 C" g5 BadOpenStatic,: q; O* _& }. Q* x
adLockOptimistic,
& d. A% v" z% V! AadCmdText);. A7 t, F5 c- M. z% b. Y4 ?

  s; H! L! M" KOpen方法的原型是这样的:
7 ~" u* ~, {- j  S! mHRESULT Recordset15::Open ( const _variant_t & Source, " F6 ^! P/ V, Q  I9 d$ T
const _variant_t & ActiveConnection, 2 y* y2 `" k3 C
enum CursorTypeEnum CursorType,
' L. c; ~1 @& v% Tenum LockTypeEnum LockType, 5 @2 K7 i3 W) i9 h7 Y% \
long Options )   H  @0 F; D. k3 G% f7 H1 o+ N

2 m% G/ M7 a& l5 f" z1 c3 O1 x9 b其中:
% ~4 i) ~3 ]+ i, \: R8 V1 F' S+ ^0 G5 t8 E& _" s( U, Q
①Source是数据查询字符串
, c; r7 p* M5 i! p! K, S②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
9 |& b4 z; I" O9 I9 z" h③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:1 f& B" y! m. s& M5 g0 |8 z

- S  d6 b5 `3 w2 g2 O% C$ k. L/ Venum CursorTypeEnum: ?/ ?+ S$ t1 T& Z# @% ^' _  r) {
{
2 {2 p9 a/ Q  K/ ^  W1 aadOpenUnspecified = -1,///不作特别指定
7 a8 d% {: u8 {+ {8 u4 C2 h% S& Y, e& dadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
. i$ U, J" Z1 D$ ~0 j' iadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
3 X5 L4 ^# E* F; e( o
# b9 p0 o, V- o' G  F9 CadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。( l" r/ ~8 `# K+ \! j
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
2 Q" ?# a2 a2 T  _};8 O, O" \8 ]. [
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:. q, W- Y$ q2 O* u

! F) Q  M: Q, f. Eenum LockTypeEnum
! J) ?' G: T! n; j/ i4 B( n$ U% [+ S{
2 Z! F7 Y" l' e( i, b  F4 ^adLockUnspecified = -1,///未指定
( J4 h3 s4 L, e4 r9 J9 cadLockReadOnly = 1,///只读记录集+ Z& i1 O" z0 G  u! n- b8 {
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制. Z( v1 b  `; ~" A, M
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
$ w$ A0 e5 A) e+ d% N* d! q; W; ?adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。4 F- L$ r- d9 v, @1 p! |2 h
}; 1 _9 ~9 B! I8 M6 R9 c: q! E) m
5 Y8 |- Y5 M0 F8 Y
⑤Options可以取如下值之一:
/ h& e6 k3 g2 |" l3 hadCmdText:表明CommandText是文本命令3 e8 j: e! X4 B# q1 }
adCmdTable:表明CommandText是一个表名
3 r/ R" [1 a0 XadCmdProc:表明CommandText是一个存储过程
* I4 t9 j% _/ t) Q5 U9 x3 m2 badCmdUnknown:未知
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:22 , Processed in 0.416319 second(s), 52 queries .

回顶部