QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
# Z, `$ J( p$ t7 p7 @1 Q/ a5 O9 s2 r6 Z3 m2 n
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;3 f- ?( |8 t" J
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");  i* q5 @  P# \  _3 N0 e* ?& l
SQL命令的执行可以采用多种形式,下面我们一进行阐述。2 e8 }7 p: E, Y! a2 S3 t4 q* j

# o$ _2 y( P  O: a6 ?( j. X( J  (1)利用Connection对象的Execute方法执行SQL命令, |, Q) y& U* d: `

* q$ v6 ~7 }; [% J& K' d' A& a% A8 s  [  Execute方法的原型如下所示:
* Q- O5 Q# E& _% k) c- K* D- a6 L3 i0 C9 @
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
9 d, j6 \) x9 Y. Z, ]# `- D8 j
! z- {/ b% S. K& F8 m其中CommandText是命令字串,通常是SQL命令。
& S# r& k9 b" t& I8 q( W7 K+ _& g参数RecordsAffected是操作完成后所影响的行数,
5 j/ X/ y, u( P参数Options表示CommandText中内容的类型,Options可以取如下值之一:: q( H, d) b$ l- x, {
adCmdText:表明CommandText是文本命令
  |, @. J5 f$ w8 F3 `) d" |5 vadCmdTable:表明CommandText是一个表名
7 n, o# J* @. i; _6 m/ Q& x4 m) CadCmdProc:表明CommandText是一个存储过程$ U, r$ M/ b: d( `# P1 I. t
adCmdUnknown:未知
, A9 l* B( r; ?$ Y; x8 c* W7 `/ J0 t
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 * G9 h3 ~  K2 a1 }7 @) U
_variant_t RecordsAffected;1 I8 @3 Q. n1 U6 P, m
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
! \: d, ~/ f  U+ g* ~" b( j0 m: l* [m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
8 p6 p  t+ p+ W# }&RecordsAffected,: d! X' t4 P2 ?7 C& P+ \
adCmdText);& h. b: [. z2 C4 O: |" b8 Q6 [
4 a' g/ I2 F0 ?: z
///往表格里面添加记录
" \  t9 w2 i& a" b2 P( m- Q- Em_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
! x6 z, A. S% Q% x' H) o7 J5 k7 T( W- d& ?& U. z9 ?
///将所有记录old字段的值加一
% B! g& M2 C9 w2 q6 }  m- hm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);; E/ G5 Y! A% P& [' m

# P! O0 n9 C! U6 B  T) W& E4 o0 ~0 ~  R* [///执行SQL统计命令得到包含记录条数的记录集
8 b2 J# Q, c( B7 i  xm_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);5 L& W& l- B6 g: I. C; P
_variant_t vIndex = (long)0;
3 v; w2 S; K% Y7 r% @! ]_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量; Z$ `6 g' o# @" o
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
' Y; R+ h8 T/ i, i% b: Im_pRecordset->Close();///关闭记录集) b& D# N; m' I- o# C
CString message;
- T& x! Q* A9 U' p5 Ymessage.format("共有%d条记录",vCount.lVal);1 L; w, c6 \) G3 t  _' O
AfxMessageBox(message);///显示当前记录条数3 u% S/ U! J. R" y7 K+ F4 C
5 L8 v+ z" \8 B% P, p# }
(2)利用Command对象来执行SQL命令
6 e( {9 L2 M. s; A7 D+ ^: `, w4 l( |6 I7 D
_CommandPtr m_pCommand;
6 z+ e. B* J% N7 m8 @m_pCommand.CreateInstance("ADODB.Command");+ g3 Q# z+ v) j  F
_variant_t vNULL;
' H2 V. i9 [9 @+ W& n' X0 e9 P' TvNULL.vt = VT_ERROR;
3 n% o% p) Z3 X) BvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
! l# G8 E' \9 [) V, Lm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
! S. Y' p# M: [' D( g% N+ Z7 N( A. Bm_pCommand->CommandText = "SELECT * FROM users";///命令字串( F# p5 Q- S3 z% h
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集& J: ]: {! x, N
8 t4 q3 Q1 x0 ~
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 ! D* D4 T2 ]6 g9 v5 |; s! ]

7 o+ W" ?+ Y4 A$ _. r2 L# S  (3)直接用Recordset对象进行查询取得记录集
8 r$ i5 l# ?# a! E" r9 m) i! f/ K% E& y" L' z2 {
  实例—— 9 c, |. K$ ~, D( ]
) h" M& c* l. D+ Z
void CGmsaDlg::OnDBSelect()
" [) S( M; w  V{
2 z4 ?8 c/ E5 D  P- j  T// TOD Add your control notification handler code here
: W' K/ w1 Q, p* r3 o0 Z$ C( t_RecordsetPtr Rs1; //定义Recordset对象
! p7 r. p  {* {4 [; x_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
' G3 K* ^, W5 q( q7 ^2 R_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
9 K, f+ ]% Q) q::CoInitialize(NULL); //初始化Rs1对象' r  T" f  K" \5 [
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
5 e" W: X. Z& R' b% W& N//省略对返回值hr的判断   V6 ^( ~' J1 C) {4 d. R
Rs1->Open( Source,
$ t+ L  K- D; L2 O# V- y6 AConnect,
$ s& }5 n4 `" t5 z% M  ^4 p' [adOpenForwardOnly,, V$ R% X1 P2 s+ B
adLockReadOnly,* X/ B! h2 h5 E/ ^2 x* X0 l' P
-1 );
  a- P8 @2 D" B  u7 b! s5 __variant_t temp=Rs1->GetCollect(_variant_t((long)0));$ g0 e) E4 K; o2 o) n
CString strTemp=(char* )(_bstr_t)temp;# M' K" y9 P  k* C; C% E* ?
MessageBox("OK!"+strTemp);$ s. o2 O) D  B
}
% J6 w/ O& Q: N1 V+ x
* w/ e* M5 j* V' Z例如
  K- m. O5 f% Z% q. ym_pRecordset->Open("SELECT * FROM users",5 d! [& z) t; z1 I. Z7 ~! [
_variant_t((IDispatch *)m_pConnection,true),
) b% s, A, U1 @- kadOpenStatic,
" a, j! D  l$ t; ]0 d( fadLockOptimistic,; c/ n$ w3 u6 e' u/ v% \
adCmdText);
. T) ]* I& V% n' \3 n! D# a7 V9 |4 n6 b+ |" y
Open方法的原型是这样的:
6 V, K  u$ M( XHRESULT Recordset15::Open ( const _variant_t & Source, 0 x5 N3 J5 i1 r, c
const _variant_t & ActiveConnection, 8 X" X' ?" B8 y0 e' _  ]& ~0 Q
enum CursorTypeEnum CursorType,
! Q8 Q7 `! m4 d% [& Penum LockTypeEnum LockType, " }+ [- ?5 ^  i; ~  ^+ o
long Options ) * I5 G7 Z9 |& T0 o2 k3 X
  w1 G- x( ^* X( n
其中:
- Y4 @- I1 S+ Z8 B& x: J  q4 v& V  K6 S9 P
①Source是数据查询字符串
( ^' o& L! r$ I+ V: {$ G②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
; J; q) {5 }4 f( }) K③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:7 R8 j& c, b1 n8 ^% b

* N; B5 k% H9 i6 {# M3 ^4 ?- p  \enum CursorTypeEnum
2 e3 h8 j% h$ m+ g& l{) k" j0 e' I" g6 R% Y, c
adOpenUnspecified = -1,///不作特别指定
6 T! H- E2 e& [* z$ G- \adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用5 N: A/ \! {* _& T& e
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。$ r! v; \3 y" d9 }5 H6 x6 ]& M

* R2 @' h( K* [& _adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。& }. {9 f/ u5 j) A; o. @0 r9 g
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。# {9 h0 a8 [  d/ P2 L# |" q
};! n, Z8 t# A. G) b7 _
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
" B+ v+ B4 _' c% W7 w* A# q
: F+ v% ?. S, D  Genum LockTypeEnum+ Q+ m: ~! o0 Y4 a
{1 M. M$ S0 ~' b
adLockUnspecified = -1,///未指定
2 o. C8 V1 X* ?8 \' s0 F( P, }9 |adLockReadOnly = 1,///只读记录集& C* e1 J' z- u1 p
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
2 K' }9 Z  P) c  O% NadLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作* S1 N- W2 @% g8 Y+ y# I
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。  q+ @+ S! @& e6 B. b5 R- N: X. T
}; . b* \* w4 v$ U) y5 a

7 }9 A( }. ~6 ?' k3 p! B5 q⑤Options可以取如下值之一:
. z. O7 }/ w  OadCmdText:表明CommandText是文本命令
) V4 b; W& E" s7 Z# DadCmdTable:表明CommandText是一个表名
* b7 h7 x' R7 h/ i9 k" J. ]adCmdProc:表明CommandText是一个存储过程% j; t# {+ B4 q
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 14:28 , Processed in 0.430610 second(s), 51 queries .

回顶部