ADO数据库编程入门 liandong(原作)[3]

[入库:2005年8月18日] [更新:2007年3月27日]

本文简介:选择自 westerly 的 blog

   cstring sname=(char*)(_bstr_t)(m_precordset->fields->getitem
    (_variant_t("姓名"))->value);
   if(::messagebox(null,"姓名="+sname+"\n删除她吗?",
    "提示",mb_yesno | mb_iconwarning)==idyes)
   {
    m_precordset->delete(adaffectcurrent);   
    m_precordset->update();
   }
   m_precordset->movenext();   
  }
 }//try
 catch (_com_error &e)
 {
  ::messagebox(null,"又出毛病了。","提示",mb_ok | mb_iconwarning);
 }
8、使用带参数的命令
command对象所代表的就是一个provider能够理解的命令,如sql语句等。使用command对象的关键就是把表示命令的语句设置到commandtext属性中,然后调用command对象的execute方法就行了。一般情况下在命令中无需使用参数,但有时使用参数,可以增加其灵活性和效率。
(1). 建立连接、命令对象和记录集对象
本例中表示命令的语句就是一个sql语句(select语句)。select语句中的问号?就代表参数,如果要多个参数,就多放几个问号,每个问号代表一个参数。
_connectionptr  conn1;
_commandptr     cmd1;
parametersptr   *params1 = null;   // not an instance of a smart pointer.
_parameterptr   param1;
_recordsetptr   rs1;

try
{
 // create connection object (1.5 version)
 conn1.createinstance( __uuidof( connection ) );
 conn1->connectionstring = bstrconnect;
    conn1->open( bstrempty, bstrempty, bstrempty, -1 );
    // create command object
    cmd1.createinstance( __uuidof( command ) );
    cmd1->activeconnection = conn1;
    cmd1->commandtext  = _bstr_t("select * from mytable where age< ?");
}//try
要注意命令对象必须与连接对象关联起来才能起作用,本例中将命令对象的activeconnection属性设置为连接对象的指针,即为此目的:
cmd1->activeconnection = conn1;
 (2). 创建参数对象,并给参数赋值
// create parameter object
param1 = cmd1->createparameter( _bstr_t(bstrempty),
       adinteger,
       adparaminput,
       -1,
        _variant_t( (long) 5) );
param1->value = _variant_t( (long) 5 );
cmd1->parameters->append( param1 );
用命令对象的方法来创建一个参数对象,其中的长度参数(第三个)如果是固定长度的类型,就填-1,如果是字符串等可变长度的就填其实际长度。parameters是命令对象的一个容器,它的append方法就是把创建的参数对象追加到该容器里。append进去的参数按先后顺序与sql语句中的问号从左至右一一对应。
(3). 执行命令打开记录集
// open recordset object
rs1 = cmd1->execute( &vtempty, &vtempty2, adcmdtext );
但要注意,用command和connection对象的execute方法得到的recordset是只读的。因为在打开recordset之前,我们无法设置它的locktype属性(其默认值为只读)。而在打开之后设置locktype不起作用。
我发现用上述方法得到记录集rs1后,不但rs1中的记录无法修改,即使直接用sql语句修改同一表中任何记录都不行。
要想能修改数据,还是要用recordset自己的open方法才行,如:
 try{
   m_precordset->open((idispatch *) cmd1, vtmissing,
    adopenstatic, adlockoptimistic, adcmdunspecified);
  }
  catch (_com_error &e)
  {
   ::messagebox(null,"mytable表不存在。","提示",mb_ok | mb_iconwarning);
  }
recordset对象的open方法真是太好了,其第一个参数可以是sql语句、表名字、命令对象指针等等。
9、响应ado的通知事件
通知事件就是当某个特定事件发生时,由provider通知客户程序,换句话说,就是由provider调用客户程序中的一个特定的方法(即事件的处理函数)。所以为了响应一个事件,最关键的就是要实现事件的处理函数。
(1). 从connectioneventsvt接口派生出一个类
为了响应_connection的通知事件,应该从connectioneventsvt接口派生出一个类:
class cconnevent : public connectioneventsvt
{
private:
      ulong   m_cref;
public:
      cconnevent() { m_cref = 0; };
      ~cconnevent() {};

      stdmethodimp queryinterface(refiid riid, void ** ppv);
      stdmethodimp_(ulong) addref(void);
      stdmethodimp_(ulong) release(void);
      stdmethodimp raw_infomessage(
         struct error *perror,
         eventstatusenum *adstatus,
         struct _connection *pconnection);
      stdmethodimp raw_begintranscomplete(
         long transactionlevel,
         struct error *perror,
         eventstatusenum *adstatus,
         struct _connection *pconnection);
  ......
};
(2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现了):
stdmethodimp cconnevent::raw_infomessage(
         struct error *perror,
         eventstatusenum *adstatus,
         struct _connection *pconnection)
         {

本文关键:,ADO,
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top