数学建模社区-数学中国
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
[打印本页]
作者:
god
时间:
2005-3-30 22:53
标题:
[转帖]在Visual C++中用ADO进行数据库编程(中)
4.执行SQL命令并取得结果记录集
& Z/ }: D4 Q3 ^$ D
$ m% r! m' @' I# y' o
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
; Y* A. L' g: L6 \! W5 e
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
5 k" j: w4 j' }3 W7 Z
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
# Q8 z" b! w5 I$ x: _5 q9 K" }
2 E$ y# x+ ~2 \: k1 p9 n! R/ R+ n
(1)利用Connection对象的Execute方法执行SQL命令
+ `0 d$ k6 I) a, q" o# p
6 J9 J( s- C' h- R
Execute方法的原型如下所示:
3 `' c* `) r! F, [
6 F7 f$ Q8 E" |; f: k1 u6 i- ~
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
1 Q% r( S9 a- _
7 Q7 d* b; M$ ?1 l
其中CommandText是命令字串,通常是SQL命令。
, A. {4 B% \* c, z2 Z3 D
参数RecordsAffected是操作完成后所影响的行数,
" O1 ^$ @* X. l$ L
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
$ Q1 N) A6 f9 _. E# S2 n% g5 y2 m
adCmdText:表明CommandText是文本命令
6 T; y' C+ f* G7 u4 s4 f- I
adCmdTable:表明CommandText是一个表名
% t; |4 c# w3 y% z4 `
adCmdProc:表明CommandText是一个存储过程
( X+ D4 _! Y+ E5 r, @" `& a
adCmdUnknown:未知
+ ~, j+ T: n+ [0 @% _
9 ^( f/ p) B0 t1 P
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。
! ~) B0 ~0 d* y0 L& S- ~6 \, b
_variant_t RecordsAffected;
z2 E; j. p0 e1 O
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
# \+ l7 ]: K7 v9 k
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
3 ?7 `; B& h# V) _& Y
&RecordsAffected,
5 o+ [) B' D% O
adCmdText);
4 y2 D" D$ ?- O) {6 J
2 o P5 H' c g9 G' ^1 h, W0 t: A
///往表格里面添加记录
5 G* m9 S5 P3 q. m" p5 D
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
+ K: y4 q" ~6 s* K+ ]: J) K
: I3 l+ f* X: E. a, A
///将所有记录old字段的值加一
/ t) s1 [$ @+ v2 G5 r- f
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
' j- y4 k, t# `; y0 ~- L! U
. O3 `( W3 i; W
///执行SQL统计命令得到包含记录条数的记录集
" s$ @0 F* U7 [5 y0 t W
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
6 ?4 r: @% u3 c! x' {/ K1 K" H9 {+ t
_variant_t vIndex = (long)0;
! j5 o: K5 F* i* N3 l& Q; E, g
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
# b4 L* W' N" N- a8 j& r& H6 y
上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
! z4 f0 d+ W# m/ \) n
m_pRecordset->Close();///关闭记录集
6 V5 w# z2 A& S' c, h8 b
CString message;
0 Q' B9 f- ^. [6 m1 o% O
message.format("共有%d条记录",vCount.lVal);
1 h: B/ Z: I2 T2 s& h! k
AfxMessageBox(message);///显示当前记录条数
& k- F8 r6 m1 I+ l, J
; T6 D! W* [$ b- X+ h( ~
(2)利用Command对象来执行SQL命令
* K4 }' n$ t1 V' l h
' J4 w& {1 v& A: V' u
_CommandPtr m_pCommand;
' h$ ]8 o: y0 G9 s% I. {: H
m_pCommand.CreateInstance("ADODB.Command");
0 f- H6 p* n3 b$ u
_variant_t vNULL;
+ k+ d* c0 ^2 }, K7 n
vNULL.vt = VT_ERROR;
; r$ u9 h: H; p/ _' w, a) t. e; `
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
% e8 V( a( M6 M% C
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
9 n9 W& W6 }- Q' S7 v
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
) X" _/ Y$ {7 n: J
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
: G; j! H; N8 O2 H6 {
& B7 V" h2 y5 p/ Z
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
+ ^% q. R6 [8 S9 Z& ~2 M# o" E7 Q
( \4 a7 ^- C3 O3 m |4 I7 e( X
(3)直接用Recordset对象进行查询取得记录集
* n9 |' B1 \; H% p$ Z
* K9 R [( y0 ]4 n( C
实例——
7 h2 C6 F, q; N( S0 C
5 X1 V) x/ x3 j: V! G. A
void CGmsaDlg::OnDBSelect()
# q1 F6 M7 l$ H# s$ u' s& i/ b" g
{
: q# B8 J; a. ^' R
// TOD Add your control notification handler code here
. o3 n# m/ Q$ W
_RecordsetPtr Rs1; //定义Recordset对象
6 }% Q1 L" V! B1 Y- _
_bstr_t Connect("DSN=GMS;UID=sa
WD=;");//定义连接字符串
" S3 O7 L; J: @& l- g
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
9 G- Y3 O; X9 r$ B' m; e& t u- Y
::CoInitialize(NULL); //初始化Rs1对象
. {9 B7 x& l" _ g3 I
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
9 s3 ?6 ~0 w |4 ^$ J
//省略对返回值hr的判断
. n. f; G" V& o9 [9 D% s+ c+ G4 U
Rs1->Open( Source,
2 k( ^" `5 u9 r
Connect,
' k' t/ q% |: Z! }5 r# H3 W7 G
adOpenForwardOnly,
, I, X4 n3 G& X& e0 R( b2 a/ V: i
adLockReadOnly,
) |6 D" _7 j) {8 G, r* q1 ~0 s
-1 );
4 I) L3 @+ S: u* B7 f+ J$ ^3 M# Q
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));
7 I; B; _' b* m: p0 s; I4 l
CString strTemp=(char* )(_bstr_t)temp;
, f+ N, |7 ^+ i
MessageBox("OK!"+strTemp);
; a/ b0 j% W+ A6 A U/ j, H
}
# f* r7 |6 c3 F3 D( @7 N/ `
! Q6 X3 [3 [) w3 R& I" F
例如
$ G7 g# f8 q8 `
m_pRecordset->Open("SELECT * FROM users",
6 k1 A( n1 L& W3 p- G2 a2 B$ m3 l
_variant_t((IDispatch *)m_pConnection,true),
: |/ f7 O1 H/ I4 c2 Q" o% \+ \/ b
adOpenStatic,
; B" d/ e1 k" }$ Z
adLockOptimistic,
7 l7 g/ v) e2 P" W( d; E" |; b: {) J
adCmdText);
- e0 r1 D% d; ?6 S
6 _4 O7 K1 _- G2 y* C/ b% @( `, o
Open方法的原型是这样的:
4 h5 o5 { c/ K' f3 P# Z
HRESULT Recordset15::Open ( const _variant_t & Source,
* e1 ` V7 i4 R4 y+ u
const _variant_t & ActiveConnection,
. K8 A* H9 d; U7 y, T% B$ J+ D
enum CursorTypeEnum CursorType,
1 p$ P) P4 Q- p
enum LockTypeEnum LockType,
5 ?' b9 S+ O' G* [" m
long Options )
L5 l6 q) \0 h
6 F0 f4 [+ L3 {& U7 L
其中:
, ?5 F' Y; {$ C% Y: \
1 F7 a2 A( e; ~/ o2 ?
①Source是数据查询字符串
: I) _: p( z1 V* T4 I
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
: {4 u, b; R8 I. J
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
0 ` x C( P i" A' i
' U8 ^2 q) x' w8 h# i
enum CursorTypeEnum
3 r% U+ {" q! P) e, d) T B- m: y8 ?, _
{
: `# n0 l& ]; o
adOpenUnspecified = -1,///不作特别指定
; V' K3 p0 S# V! O7 l( k
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
3 R4 c! E/ U6 M) c
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
8 J% f# d! ?/ {0 ^
2 U2 v8 r, _' b# a7 [* c! B
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
% `0 f+ U6 g) r- [0 A3 m: c3 X3 i
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
/ c# B4 Z( p) d
};
* X% B3 n, R9 n5 R
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
" t& c4 @* ], V7 T& W# k
- Z' c; l8 x" t
enum LockTypeEnum
& ^+ d8 C0 h! G: I6 F s
{
$ d( B/ G. I1 A9 C+ t! c" w% C
adLockUnspecified = -1,///未指定
( L7 X& Q% Y3 |& H2 u5 M
adLockReadOnly = 1,///只读记录集
; Q3 Y# z O* V8 L
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
3 u/ d! n4 N5 [- F0 _; } H
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
5 Z+ ^9 s `: a! `
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
, k; E% \ s3 H) a- c& j. l8 c
};
F+ z) m, j: z8 I! c) f. {: l# K
- v3 v/ a! o9 @3 k' W
⑤Options可以取如下值之一:
u+ q" k$ S+ `/ X6 g
adCmdText:表明CommandText是文本命令
8 Z7 { Q( x2 K& z& Q, N
adCmdTable:表明CommandText是一个表名
! g# a9 V: m, S
adCmdProc:表明CommandText是一个存储过程
2 C* ]1 T$ L1 b4 Q S1 k
adCmdUnknown:未知
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5