数学建模社区-数学中国
标题:
[转帖]在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 \. |& d
SQL命令的执行可以采用多种形式,下面我们一进行阐述。
) 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, U
0 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$ ]" \: d
adCmdTable:表明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 K
m_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 U
adCmdText);
% 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 Z
m_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 x
m_pRecordset->Close();///关闭记录集
& ]# X9 }& U3 l
CString message;
4 x" |- l b# l- I" h9 r+ X. o! D8 M
message.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 O
m_pCommand.CreateInstance("ADODB.Command");
% |+ x R( U% o+ A
_variant_t vNULL;
/ G; E* ]' V8 b k* B
vNULL.vt = VT_ERROR;
2 H) |1 n ~2 z
vNULL.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# H
m_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: C
void 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=sa
WD=;");//定义连接字符串
, 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 Z
Rs1->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 t
CString 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; N
m_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 d
adCmdText);
! 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 ]$ J
const _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 CursorTypeEnum
1 @( F' I* ^; C/ a. \" G
{
! u: ` u0 {+ t' o0 f
adOpenUnspecified = -1,///不作特别指定
2 b1 E# B. v5 A K) |6 u/ X) R
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
1 }( I' r! v+ U0 T% f
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
8 U _ K+ { [6 Y
. U0 V2 f0 }6 G+ j3 _0 Y: e1 S8 [
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
6 W2 ?" i# o! v0 e; @, m
adOpenStatic = 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 LockTypeEnum
7 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 J
adLockReadOnly = 1,///只读记录集
) i/ O8 R' t* ]# M% R) O- q* N
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
H; u% Y( T9 L. k* }5 e- B
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
9 [2 M/ A; ~ P( N5 ^8 q
adLockBatchOptimistic = 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/ N
adCmdProc:表明CommandText是一个存储过程
' j2 w3 o7 |7 W: G. }& K
adCmdUnknown:未知
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5