QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集+ c( `, E* X: r9 f# q, h6 t5 S1 H
' ?; u; C1 F# O) T& Y
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;+ I* l) T, H' h* X- ~' {
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
/ \4 P; W3 g# g  G  s: ^SQL命令的执行可以采用多种形式,下面我们一进行阐述。  n" _8 A! H1 z, }% h. j8 S
0 X# x, J* Y8 `6 O& c3 b8 F* q
  (1)利用Connection对象的Execute方法执行SQL命令& q1 r4 ^5 p4 G) q! g
. ]% v& _. R2 F2 k3 j+ y) l, ]
  Execute方法的原型如下所示:5 }# }" ]& s+ ?# d

( K3 i0 h0 T3 v5 D$ S5 J( q_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 3 u) q3 R1 r. u

; x* x5 Q' j; L% e- [. \其中CommandText是命令字串,通常是SQL命令。
& {, [0 K  s5 J% M# n- W参数RecordsAffected是操作完成后所影响的行数, ( N. p  _# @$ ]% D) H' f$ Z+ `
参数Options表示CommandText中内容的类型,Options可以取如下值之一:
/ b; k: U. M& q" radCmdText:表明CommandText是文本命令; _. u/ @9 F" J) @# ?$ r
adCmdTable:表明CommandText是一个表名' ?: c' q; K/ }) g* `( D% E. q5 T
adCmdProc:表明CommandText是一个存储过程
+ H4 l" [/ w' F. PadCmdUnknown:未知/ U; f$ r1 P2 ~, J+ I) N/ F9 I4 j9 e

4 [# A" o4 D3 P; jExecute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 8 L6 H- }* ]) E, ^( o" Y
_variant_t RecordsAffected;
( [; u/ ^8 q+ q6 l& K///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
/ e; g7 J. `  \) B, N& s1 Gm_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
( w6 _+ S5 [6 }: ^&RecordsAffected,
  u. W3 @) H2 y' h! q- P$ ZadCmdText);
" h: ^" V' F4 r- w0 W# B# c  c3 |& D
1 P3 d4 k6 \/ w  J- E9 p///往表格里面添加记录
' o1 K8 L' h% n% Om_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);
9 Y, p: e/ e/ k) u  _2 P3 D) l. K
///将所有记录old字段的值加一9 ?" ]) [6 \2 h) l% _
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
6 {6 A0 h6 _- ~# r  R& i
" t: t$ {( q$ z# M: y3 N///执行SQL统计命令得到包含记录条数的记录集+ E  L: O6 Q1 b7 l) E1 N3 P: j( B$ E
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);6 e- [6 a$ C9 k
_variant_t vIndex = (long)0;* C9 O- t0 E! c1 s. d# z& a: y
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
2 x4 `- Q& U# Q, b上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
/ {7 X% N) Q+ X- e+ n$ o* l( ym_pRecordset->Close();///关闭记录集) f- @' a7 c, ?  o
CString message;% K0 H: L% ?- r% f( Z
message.format("共有%d条记录",vCount.lVal);7 ~$ C1 p& I% A
AfxMessageBox(message);///显示当前记录条数4 S- D6 U" {) {
% h3 `7 l! e* N$ o# @$ E) j6 |
(2)利用Command对象来执行SQL命令 ( h2 w( H7 }& @" I+ P# T" n* X, ?
* m! g! U' N$ |+ W% X
_CommandPtr m_pCommand;
  o- ~' D: O- J9 T- V( m9 s+ A" ]* ym_pCommand.CreateInstance("ADODB.Command");
1 V8 `- |  x7 F, e_variant_t vNULL;0 G: ~. @: h% Z4 W! T+ K- u$ F: V- l
vNULL.vt = VT_ERROR;( ]3 o8 L9 {( _) w) _  B4 B" T
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数# z  l& V2 @3 I; E
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
; O# H" ?0 H$ G0 ]$ Dm_pCommand->CommandText = "SELECT * FROM users";///命令字串
. C7 c- @( ~* z6 R+ C( Mm_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集% g8 C! }5 a2 m- O* \& c& }
% |# T& B8 R  T
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 + P9 W: J3 M) E' W/ K
6 O5 H1 ~' [" j: Y
  (3)直接用Recordset对象进行查询取得记录集( _3 c: S4 Q6 p4 Z

- x: G3 y1 I! \, _5 `9 _  实例—— . t9 d- j2 t7 e/ |
. F. C  I# D- O! |
void CGmsaDlg::OnDBSelect() 3 u# }: Q( r+ A
{
; G; y( t( u( B% Y* V// TOD Add your control notification handler code here+ O& d2 t+ N! y
_RecordsetPtr Rs1; //定义Recordset对象
  Z- `6 Y/ n; C( J+ ~% D/ {_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串" V; p% \, o  m
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句
$ @' i1 Y2 y5 s::CoInitialize(NULL); //初始化Rs1对象
% V; L* I) ~$ l( [& NHRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
$ q7 J! M" o( r//省略对返回值hr的判断
# x$ H, Z; X8 ~8 L$ _0 _Rs1->Open( Source,* a) Y  P. ]2 M* |7 N7 {
Connect,
! p+ F0 ]+ ?4 J% {4 badOpenForwardOnly,
1 L, F" J# r7 X. C/ a  VadLockReadOnly,2 h5 L! ?! f/ T& i
-1 );
$ d0 w9 d2 I7 K/ j! J_variant_t temp=Rs1->GetCollect(_variant_t((long)0));- R5 j# e! Z, x1 H9 M- S
CString strTemp=(char* )(_bstr_t)temp;  V0 g7 ?0 h' X4 o2 M. v) @
MessageBox("OK!"+strTemp);* W, I# u+ D, b2 N0 A* @
}
; ?5 R* |2 P% \) O0 x& N* r- O) J+ S  ?! s% R7 H5 o$ l5 k% L
例如 % D% P2 W" f- E% b' a) ^) g3 U
m_pRecordset->Open("SELECT * FROM users",
" C" @) i) C7 ^6 s_variant_t((IDispatch *)m_pConnection,true),
8 F+ h6 D* T( }2 @adOpenStatic,) q! g1 G: Y9 M( x) g$ Y5 L& ]
adLockOptimistic,, O: Z' G# B5 T
adCmdText);
; Q( Y! b0 X9 |
  T( \( Q- u) p9 k& d  dOpen方法的原型是这样的:0 J* J% j9 H& k% h$ o! d
HRESULT Recordset15::Open ( const _variant_t & Source,
1 N9 g- e3 a5 d5 @const _variant_t & ActiveConnection,
5 R% k+ V0 P3 m0 y; nenum CursorTypeEnum CursorType,   t5 F! ]' U$ [6 O, d
enum LockTypeEnum LockType, / t3 ^; s  C7 m8 z  k
long Options )
9 {7 o5 B7 `" Z2 x% D5 H& {, Y$ ^3 S. M# c
其中:+ {3 |; w! x+ R6 T6 U
' w' i' B4 \0 g4 }+ r# q
①Source是数据查询字符串2 [" Z( U: A& P
②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) ( B% U; N- R* |- `+ j& B% u, n, i
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:
( U9 ~0 Q3 v7 K" W- e
; H- `& w7 ?7 u( V& r) Kenum CursorTypeEnum
- B6 D7 y* `9 f{& a0 F+ u) H# d2 b$ e! r
adOpenUnspecified = -1,///不作特别指定( p, H. M0 H& T% j+ _6 A. K
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
! @. E  {2 t% u0 NadOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。" g! n! A. G1 X" Y7 g. W6 C

+ }& W/ Z% A: ]5 N: vadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。' y3 ]4 M: I. T; }* T& N( S" I
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。! a# P5 t" q4 N1 }
};8 g" |, q& R  W; V6 p
④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:
3 e9 Y9 S) w0 R/ A1 c  |6 |# u( I& x, A! A
enum LockTypeEnum+ [8 K/ M) N5 X8 P/ Z8 _+ i
{5 k4 @/ T& w9 ]6 m% X  Z
adLockUnspecified = -1,///未指定6 ~) U( W2 m  y% ?  k: c
adLockReadOnly = 1,///只读记录集# R) W3 W. i$ @! }5 [
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制$ ?4 M3 o4 W& e6 w) c9 g; \
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
3 [6 X: T8 `& ~) w* QadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
1 Y# S( X( W  {7 j" K};
  Q& ?/ A1 c# T7 b. S6 O, Y' `% X3 V  H% B
⑤Options可以取如下值之一:
( F! d& b& j0 Q2 nadCmdText:表明CommandText是文本命令
" ]" B/ l2 Q$ iadCmdTable:表明CommandText是一个表名8 o, R* S0 x* i! ?  T- J
adCmdProc:表明CommandText是一个存储过程
; \  c4 L- w" S$ B0 u  o+ TadCmdUnknown:未知
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-9-3 17:45 , Processed in 0.448464 second(s), 51 queries .

回顶部