数学建模社区-数学中国

标题: [转帖]在Visual C++中用ADO进行数据库编程(中) [打印本页]

作者: god    时间: 2005-3-30 22:53
标题: [转帖]在Visual C++中用ADO进行数据库编程(中)
4.执行SQL命令并取得结果记录集: b# R8 j1 B$ A% O/ c. Y, s" i

& X0 c" S0 y& h1 ?3 F3 T  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;6 a+ \% s, f4 @* Y; J7 h/ Z
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
) m1 h! b# i  C$ {4 \. |& dSQL命令的执行可以采用多种形式,下面我们一进行阐述。
) e, ]4 [, L& u6 `
. p' N$ Z/ w. k6 g  (1)利用Connection对象的Execute方法执行SQL命令& `- E: M, e' v, u8 ?
1 [4 Q) O3 k. E5 T
  Execute方法的原型如下所示:
: N1 n3 _/ N4 F7 v, U0 w- z/ x0 Y) ]* s. x
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) : R2 f& I& Q( n* h. P; t

& S# D- ]$ M+ V) W% d  J- c其中CommandText是命令字串,通常是SQL命令。% @+ y" U/ ?5 u; U. U- _; @/ r
参数RecordsAffected是操作完成后所影响的行数,
8 H  D. q* q5 M% E参数Options表示CommandText中内容的类型,Options可以取如下值之一:% K" E1 V3 g" H4 \: s2 p, f# h/ a
adCmdText:表明CommandText是文本命令
8 m; n- t8 I$ ]" \: dadCmdTable:表明CommandText是一个表名" I' d$ T& N: P1 ?4 |- c9 @& @
adCmdProc:表明CommandText是一个存储过程1 t1 ]2 e# @) U- A+ n7 N
adCmdUnknown:未知
! c5 m& x! J6 C- ~6 X( v6 _% ^) T+ v, s9 C. s
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
* `. u( X% v" t- H) ~3 H9 R_variant_t RecordsAffected;
; v: q8 M: h6 P///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
: S  j3 k+ Y, [7 X4 y1 Km_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",8 I3 H+ R& h  K6 E4 u
&RecordsAffected,
4 x" F% |: p1 X: P. `. C6 a8 O7 UadCmdText);
% d3 }% ~" K+ T, e* ]& J& B$ G$ H; h1 M2 h
///往表格里面添加记录( o& T! w2 ~- L( r7 C9 l- a
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);# G- a$ X$ z/ ^& B2 e: L. B
. d3 B! a, J1 {! S
///将所有记录old字段的值加一
; y+ w& y6 s! m! h  Zm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
. r% X7 J3 H, U8 }& `. r7 x6 M1 @5 ]# t
///执行SQL统计命令得到包含记录条数的记录集" A4 M% P) R! w9 p# r
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
& \1 \) C/ K. U( v- I  F" }' j_variant_t vIndex = (long)0;
4 [; i5 W+ ^. J3 P( D_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
( P: t- a4 ~' i8 M( f0 |上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
! G8 s6 H+ B9 r8 xm_pRecordset->Close();///关闭记录集
& ]# X9 }& U3 lCString message;
4 x" |- l  b# l- I" h9 r+ X. o! D8 Mmessage.format("共有%d条记录",vCount.lVal);. [; r* [. {1 {* W
AfxMessageBox(message);///显示当前记录条数
* t, ]; B& \6 l4 d# u. L; I; {" z% o( B1 c" W4 f; J- ?3 G! j6 k; k
(2)利用Command对象来执行SQL命令 ; Q# w/ l9 W( V6 A
! X2 e& A0 A4 s6 O2 N
_CommandPtr m_pCommand;
3 C, z5 @/ Q7 U5 ?/ V# L  Om_pCommand.CreateInstance("ADODB.Command");
% |+ x  R( U% o+ A_variant_t vNULL;
/ G; E* ]' V8 b  k* BvNULL.vt = VT_ERROR;
2 H) |1 n  ~2 zvNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数" I) L% d( h4 s7 b1 N/ f4 K
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
  P, D& d. V" W( g$ @# @9 k; t# Hm_pCommand->CommandText = "SELECT * FROM users";///命令字串
: x% S+ A$ c; I( c4 p2 _m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
7 B/ v% h: I5 f, a* [' [6 ]  ]) _$ K. t# y
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
- N' C- B0 x% T8 K' M2 k& [9 \% J2 y0 J
  (3)直接用Recordset对象进行查询取得记录集
6 g: z& e4 F$ Q8 u3 Y7 V6 J: }! \; G' |1 ?8 t
  实例—— / t( t* i4 k: x7 p2 ]" I6 ~5 R

  q; c4 T8 p4 Q8 G7 B: Cvoid CGmsaDlg::OnDBSelect()
; Z: _: B% b& o5 Q. D# }5 r{
* e" q& E# h& ?) b0 i" `, w3 X// TOD Add your control notification handler code here
/ p9 S0 ~9 ~- P; d" v2 l_RecordsetPtr Rs1; //定义Recordset对象
4 F; X  I$ F! h) [, I_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串
, e. L# S, a5 g9 P+ }6 E_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
' [& F( f  r% f# |& X- t* P8 G3 n::CoInitialize(NULL); //初始化Rs1对象# q7 N- p$ O/ K- k% S$ p" J
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
9 Z8 f7 L5 L# O( g1 _//省略对返回值hr的判断
& Q( _8 T% ~9 E+ j9 ZRs1->Open( Source,
) Q( \( l* w; U9 {! D& e$ x4 ?Connect,& z; _2 i- a0 N7 E
adOpenForwardOnly,; _5 W! W* A, m3 Z3 d  Q  u! w1 u
adLockReadOnly," ]0 d$ q( R4 P. c3 k
-1 );
& j, V2 T4 f( M( }_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
8 W. `# X1 e9 tCString strTemp=(char* )(_bstr_t)temp;
% S( ~6 X, T' [* @MessageBox("OK!"+strTemp);( f3 ^$ n: d$ w3 ^, r
}
! i6 [  G. O, |" G" g3 p# \$ F& f- \& G6 W+ U1 o9 a6 l8 m& ^
例如
$ e# C) c) g5 m; Nm_pRecordset->Open("SELECT * FROM users",
5 \( S% ?) h. G5 `: {_variant_t((IDispatch *)m_pConnection,true),4 k5 I* Y5 P5 {% i
adOpenStatic,: a; q; Y& Z/ r, S
adLockOptimistic,
* y! O; E  n1 @' M( \0 dadCmdText);! F$ P$ B: m+ `4 F9 c
: f! U' ?. d8 M) ]* y8 q% Y2 j
Open方法的原型是这样的:
" K0 d$ w0 u( H5 ^HRESULT Recordset15::Open ( const _variant_t & Source,
3 ]  C6 }: D8 n0 ]$ Jconst _variant_t & ActiveConnection, + C$ E( K& N8 A* E$ Y" z* Z
enum CursorTypeEnum CursorType, 6 K% K5 i# T  P3 W& H
enum LockTypeEnum LockType, : Y% s$ E0 q6 Q# k$ {2 L
long Options ) 5 h( y1 t( S7 |! L2 C; ~7 |

; L* f* U  I2 E# v: M其中:3 Y" _5 w1 Z3 E8 R7 ^+ {, D; x

+ _  X2 g$ i* U2 M2 N5 w- [①Source是数据查询字符串
6 P$ q7 i- s" l7 A* D+ j5 n- x②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
2 V8 p2 l" B; |( ?& x0 T1 E③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
) ~, E3 z8 Q% c- X1 m$ t* X9 C* ?; @/ _  g! Q- c4 K1 L/ l' z( R
enum CursorTypeEnum1 @( F' I* ^; C/ a. \" G
{
! u: `  u0 {+ t' o0 fadOpenUnspecified = -1,///不作特别指定
2 b1 E# B. v5 A  K) |6 u/ X) RadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
1 }( I' r! v+ U0 T% fadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。8 U  _  K+ {  [6 Y

. U0 V2 f0 }6 G+ j3 _0 Y: e1 S8 [adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
6 W2 ?" i# o! v0 e; @, madOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
. k' ~5 W  a; _3 N# p- ^: d};/ r- Y; m7 a' \" S6 F% }) S
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:$ w" {" F% Q" Z

7 `3 q$ K6 A4 s& R8 ^7 `) ?enum LockTypeEnum7 U! Z7 j4 F1 N9 f9 I
{9 }1 C# T* p1 x! k# F+ v% O
adLockUnspecified = -1,///未指定
2 v2 C$ H( m- l2 _1 JadLockReadOnly = 1,///只读记录集
) i/ O8 R' t* ]# M% R) O- q* NadLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制  H; u% Y( T9 L. k* }5 e- B
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
9 [2 M/ A; ~  P( N5 ^8 qadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。* C1 d0 ~& [+ V3 o
};
  @" g8 Y/ A/ Z* k# O
1 j7 ~  h" h: s& o) e' g4 U: l⑤Options可以取如下值之一:( s: t& W  K5 K/ o: Q9 M
adCmdText:表明CommandText是文本命令* c! Z( X* P- x0 [
adCmdTable:表明CommandText是一个表名
8 s/ g2 N5 W/ NadCmdProc:表明CommandText是一个存储过程
' j2 w3 o7 |7 W: G. }& KadCmdUnknown:未知




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5