QQ登录

只需要一步,快速开始

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

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

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

206

主题

2

听众

882

积分

升级  70.5%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-3-30 22:53 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
4.执行SQL命令并取得结果记录集
; `3 @- Z" ^' c& l7 a0 [8 i3 W& v* k0 }- b: e. ~" d
  为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
8 u" l- L( t8 H) ^- n( K并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset");
6 q, u! X& N; p2 R) n- w: GSQL命令的执行可以采用多种形式,下面我们一进行阐述。
8 G: w% X: ~+ C6 A* C$ J; h; f8 C' b% |7 h' W3 b6 y9 M$ X6 B
  (1)利用Connection对象的Execute方法执行SQL命令
1 b$ n6 H( g, F& Y, |, [
. j- d4 ~# i7 b1 m  Execute方法的原型如下所示:% D1 l( ?- E" B4 n0 O: |7 {* t

. U& I. \; |( b2 h1 x6 m_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 2 @" V  e( {  U( V: v+ ?

/ H4 v8 W7 n/ G* @+ x! S" Q其中CommandText是命令字串,通常是SQL命令。
* l' d1 b! }" L" {参数RecordsAffected是操作完成后所影响的行数,
7 H, _4 M* R- a: v参数Options表示CommandText中内容的类型,Options可以取如下值之一:" q8 z0 J. u7 c: B: o
adCmdText:表明CommandText是文本命令
' P2 m/ }+ l: k. J9 a. k3 XadCmdTable:表明CommandText是一个表名
$ b, i2 N, s( }* VadCmdProc:表明CommandText是一个存储过程
) r. Z! \) t# Z& P/ j4 f$ r1 nadCmdUnknown:未知
5 r& T& g; p) D  ]& e# k) S* K' r- A: X+ _* L  _, `" Z
Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 % [! Z2 O# d3 |
_variant_t RecordsAffected;
# `9 z+ o& v. M* G4 y9 p2 K2 s% j///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday$ d2 {1 T1 N7 `
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
8 n; ]; S/ a. h&RecordsAffected,8 ^  V$ m$ d' [0 e# m1 C, V! o
adCmdText);. r2 I; [& n$ ~6 V/ L0 c" W

( ~/ A3 b9 \! q0 e  U  J( h1 s9 `! Y///往表格里面添加记录
- [5 m$ _, y: C/ Km_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) valueS (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);3 [/ f6 p( o, O' z. n1 ^
% V# g$ R5 C+ X9 {* c( Z8 X
///将所有记录old字段的值加一
* R# N! [, @: d  E- Tm_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);$ {! ^  W9 d0 p/ y% [# Y! [2 q

* G9 p1 h9 l; R# Z$ Z  m///执行SQL统计命令得到包含记录条数的记录集
8 n' J" i7 I& G, C: Pm_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
. m8 v1 M9 z5 u. l_variant_t vIndex = (long)0;0 a! p& s" O' {: [/ D/ t: y
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
: ]* J! m0 g  {上两句可以写成— _variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));2 r; k; z, d- ^* j- Q  v3 g
m_pRecordset->Close();///关闭记录集7 @2 b$ B. c3 W5 t  B0 C
CString message;
1 S2 A* Z6 g$ [+ Emessage.format("共有%d条记录",vCount.lVal);8 e6 s* L4 O( Q) {
AfxMessageBox(message);///显示当前记录条数
( d4 f. \! Z# \* p% Q( Q! _. k. M( d8 R+ g* Y1 \* f$ Z
(2)利用Command对象来执行SQL命令   w4 X1 L6 l% b5 g( {% y' ~
6 j; G0 ~  _  |
_CommandPtr m_pCommand;: V9 W9 ]! e6 x6 U7 o
m_pCommand.CreateInstance("ADODB.Command");
0 l6 l) i% d5 a8 U_variant_t vNULL;
2 `- T0 }, M* S) g& x2 xvNULL.vt = VT_ERROR;& D8 o( O& }- E
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
  f$ [5 S, _/ y/ }% n$ l( X* Bm_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
% B1 _5 ^" L! @5 @# Z! G/ ?  N) dm_pCommand->CommandText = "SELECT * FROM users";///命令字串$ A2 V2 @; U8 E5 W& B' B! z
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集
! i: h  z& m& Z; C8 d& v% Q( i* l. l5 Z% O# u' o
  在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。 ( a' B, N' o  X

* c: z, z# E& o7 {6 q% H  (3)直接用Recordset对象进行查询取得记录集7 |8 y. Q; p& \: a
! W' q7 b/ F& e3 m+ Q: d
  实例——
8 h0 w8 [# w9 h* `& D7 Y8 a# m! X# z5 ]: `: B9 o0 M9 Z$ i
void CGmsaDlg::OnDBSelect()
: a7 Z5 T8 }1 B{8 E, _' B$ i5 g7 i. }+ A1 G
// TOD Add your control notification handler code here
2 h: R9 k- U$ P  i; T) Y4 E_RecordsetPtr Rs1; //定义Recordset对象) g1 a: F* N1 S; q/ z( v
_bstr_t Connect("DSN=GMS;UID=saWD=;");//定义连接字符串( x( w$ R; E  D1 T8 G% s2 @
_bstr_t Source ("SELECT count(*) FROM buaa.mdb010"); //要执行的SQL语句# G  ?# u* T* B) R' P( E0 \
::CoInitialize(NULL); //初始化Rs1对象5 A! B% k' F* ~# Z1 g1 {
HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );3 r2 O0 I- `7 S4 h
//省略对返回值hr的判断   H( l' |$ p; z/ ^- H$ }  e6 ^; m
Rs1->Open( Source,/ ]  J7 t/ ~* \
Connect,! \/ n1 B$ J- i* N: O
adOpenForwardOnly,* G: w) G! _& v) ?) Q: K6 p& ^
adLockReadOnly,
5 e8 Q# `3 ^+ D6 Q9 j' R* U- w: ^-1 ); . w/ @! A9 }. u  ]+ q
_variant_t temp=Rs1->GetCollect(_variant_t((long)0));, y7 i2 m3 ?$ ]3 t5 f6 u6 m/ n4 |
CString strTemp=(char* )(_bstr_t)temp;; C' G* t1 B2 b! E9 C7 u0 m2 A
MessageBox("OK!"+strTemp);1 \! o4 a( U% }$ l: d( w
}, Q2 a" d* g  ]" O
. Y, t1 o& D% _/ g! }$ Y
例如
! w6 |$ Z% X* e4 w) @m_pRecordset->Open("SELECT * FROM users",
/ j6 q- q7 }- w8 l3 d6 }0 Y_variant_t((IDispatch *)m_pConnection,true),
) b, m- M3 s$ C: MadOpenStatic,
  I& B0 p4 f+ t9 Y4 p* @, m3 cadLockOptimistic,# u" i' k. a' c  [6 t2 i- L- ?
adCmdText);5 P/ e! a% {( i0 q* ]! G
& s. \1 ]1 K# F0 l' G+ S: W
Open方法的原型是这样的:- ^- _8 R  t  g3 T
HRESULT Recordset15::Open ( const _variant_t & Source, , r$ `5 e# a; n+ X9 O
const _variant_t & ActiveConnection, / G+ c6 z1 E  i% ?3 p/ ^
enum CursorTypeEnum CursorType,
  v: ~9 l, w% N1 S( Oenum LockTypeEnum LockType,
* g  g$ V3 o7 Z( l; rlong Options ) 9 v# Y( P6 Y; X: @

6 q' N" N! _. C) f其中:0 D. o5 G  v( X" d6 `8 z" ~
$ x+ N- C" x* l8 B' E# t
①Source是数据查询字符串
; M/ N( P6 {- c2 L0 S$ ?8 P/ q②ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) & f5 w8 h- y7 P% t4 J
③CursorType光标类型,它可以是以下值之一,请看这个枚举结构:0 x! L0 B7 M$ x0 t
- J+ H, o* J$ l, W
enum CursorTypeEnum
8 w! a' [) D+ o  V{0 n, l  F" \. z7 ^* w
adOpenUnspecified = -1,///不作特别指定
8 `* M; y; F( IadOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用, w& l/ X; E& A5 U3 G
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
( t, _7 d- y! W3 c/ G' R2 b
: @) g( q0 D) l7 k$ R% q9 p' SadOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。: e0 X, A' ?' E5 ~5 g. m5 J1 V  w2 a
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
, X5 e4 |3 G! q3 ?4 `" t7 Y};
) T7 x1 a7 w1 o. C' m④LockType锁定类型,它可以是以下值之一,请看如下枚举结构:; ^7 k! X1 [  B6 Q  D( {- d

7 `+ p  p0 x/ Wenum LockTypeEnum" O8 a' S7 f/ T% x4 U
{
6 Z! I; o( ~: ~; [adLockUnspecified = -1,///未指定
/ K  S; ]* ?. e& K# |adLockReadOnly = 1,///只读记录集* f# ]/ U, ?" c  Y6 d5 R' {6 t
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制: i1 N' E( w3 C4 d0 G
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
7 K* @% s! H( T" z# _& O2 ]* iadLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。8 B! ?# t( l& q
};
/ f% h: D7 }; M8 h- g% x+ X1 o' |! E( [. N5 j
⑤Options可以取如下值之一:+ O7 z, r& I/ n3 V( K1 [3 k7 Y
adCmdText:表明CommandText是文本命令! a+ b5 e1 T/ g# v
adCmdTable:表明CommandText是一个表名0 z6 `( [9 v: l
adCmdProc:表明CommandText是一个存储过程) q1 I8 @& F" Q0 X$ c0 G5 U+ r
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, 2025-8-18 14:01 , Processed in 0.352905 second(s), 52 queries .

回顶部