visual c++ 2008进行MySQL编程(ODBC) --三 查询数据库

55 篇文章 0 订阅
10 篇文章 0 订阅

http://blog.csdn.net/ztz0223/article/details/7624726

前面两讲说到了,安装MySql数据库,安装ODBC驱动以及使用CDatabase操作数据库的基本操作比如Add del edit,链接如下:

visual c++ 2008进行MySQL编程(ODBC) -- (一) 套装安装

visual c++ 2008进行MySQL编程(ODBC) --(二) CDatabase操作数据库

今天引入一个新的类,CRecordset,其实前面的编程操作对于CRecordset类而言,相对而言就非常的弱小了呵呵,后续一一说到吧。今天的工作就是使用这个类遍历一下我们数据库里面的条目。

继续在上一个文章的工程上做这一切。

一、在对话框里面托一个listtree控件,修改属性为报表模式:

上图的黄色的框框的属性要修改report,报表格式。

二、给这个新加的list control添加成员变量,m_list_ctrl:

三、在Cmy_dbDlg类的初始化函数OnInitDialog()里面添加添加的list control的初始化代码:

  1. m_list_ctrl.InsertColumn( 0, _T("Cust Id"), LVCFMT_CENTER, 70 );//插入列   
  2. m_list_ctrl.InsertColumn( 1, _T("Cust Name"), LVCFMT_CENTER, 85 );   

四、添加一个按钮,用作查询,同时给这个按钮添加Cmy_dbDlg的单击响应函数:

查询的按钮就是上图的GetRecord。

消息响应函数为:

  1. void Cmy_dbDlg::OnBnClickedGetAllItem()  
  2. {  
  3.     // TODO: Add your control notification handler code here  
  4. }  


四、现在来实现这个消息函数,我们使用类CRecordset,具体的要使用的函数,我们看看MSDN的文档:

  1. Opens the recordset by retrieving the table or performing the query that the recordset represents.  
  2. virtual BOOL Open(   
  3.    UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE,   
  4.    LPCTSTR lpszSQL = NULL,   
  5.    DWORD dwOptions = none    
  6. );  
  7.    
  8. Returns nonzero if the recordset has been positioned before the first record. There is no current record.  
  9. BOOL IsBOF( ) const;  
  10.    
  11. Returns nonzero if the recordset has been positioned after the last record. There is no current record.  
  12. BOOL IsEOF( ) const;  
  13.   
  14. Makes the first record in the next rowset the current record.  
  15. void MoveNext( );  
  16.    


Open函数打开指定的数据库,之后才可以遍历,如果数据库为空,则IsBOF返回true,如果需要遍历每一条,则使用MoveNext( )。

使用起来就是这么简单。

五、OnBnClickedGetAllItem()的实现修改如下:

  1. void Cmy_dbDlg::OnBnClickedGetAllItem()  
  2. {  
  3.     // TODO: Add your control notification handler code here  
  4.     CRecordset my_record(&m_db_opr);  
  5.       
  6.     try  
  7.     {  
  8.         int count = 0;  
  9.         CString str;  
  10.   
  11.         my_record.Open(CRecordset::snapshot, _T("select * from customer"));  
  12.   
  13.         if(my_record.IsBOF())  
  14.         {  
  15.             return;  
  16.         }  
  17.   
  18.         while(!my_record.IsEOF())  
  19.         {  
  20.             my_record.GetFieldValue((short)0, str);  
  21.             m_list_ctrl.InsertItem(count, str);  
  22.   
  23.             my_record.GetFieldValue(1, str);  
  24.             m_list_ctrl.SetItemText(count, 1, str);  
  25.               
  26.             my_record.MoveNext();  
  27.             count++;  
  28.         }  
  29.     }  
  30.     catch(CDBException* pe)  
  31.     {  
  32.         // The error code is in pe->m_nRetCode  
  33.         pe->ReportError();  
  34.         pe->Delete();  
  35.     }  
  36. }  


现在解释一下上面的代码吧,Open函数还是请大家参考一下MSDN呵呵,第一个参数可以为:

  • CRecordset::dynaset A recordset with bi-directional scrolling. The membership and ordering of the records are determined when the recordset is opened, but changes made by other users to the data values are visible following a fetch operation. Dynasets are also known as keyset-driven recordsets.

  • CRecordset::snapshot A static recordset with bi-directional scrolling. The membership and ordering of the records are determined when the recordset is opened; the data values are determined when the records are fetched. Changes made by other users are not visible until the recordset is closed and then reopened.

  • CRecordset::dynamic A recordset with bi-directional scrolling. Changes made by other users to the membership, ordering, and data values are visible following a fetch operation. Note that many ODBC drivers do not support this type of recordset.

    CRecordset::forwardOnly A read-only recordset with only forward scrolling.

    For CRecordset, the default value is CRecordset::snapshot. The default-value mechanism allows the Visual C++ wizards to interact with both ODBCCRecordset and DAOCDaoRecordset, which have different defaults.

    具体我就不翻译了,mysql的ODBC貌似只支持snapshot,就是快照,静态的获取当前的数据库里面的条目数。

    Open的第二个参数,是一个字符串,就是用于查询数据库的的sql语句。

    编译代码,运行,我们执行一下,单击GetRecord按钮就能查询到当前的所有条目,如图:

    挺完美对吧。

    还没有结束,还要继续说说如何设定查询范围,设定排序方式等等。


    六、我们设定过滤规则,比如我想要查询100<= x <= 200范围内的cust id的条目,如何进行?

    解决这个问题需要求助于

    m_strFilter

    这个成员变量了,所以我们在Open函数调用之前,设定查询范围,如下:

    1. my_record.m_strFilter = _T("cust_id <= 200 and cust_id >= 100");  
    2.   
    3. my_record.Open(CRecordset::snapshot, _T("select * from customer"));  


    那么修改后面的OnBnClickedGetAllItem函数如下:

    1. void Cmy_dbDlg::OnBnClickedGetAllItem()  
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     CRecordset my_record(&m_db_opr);  
    5.       
    6.     try  
    7.     {  
    8.         int count = 0;  
    9.         CString str;  
    10.   
    11.         my_record.m_strFilter = _T("cust_id <= 200 and cust_id >= 100");  
    12.   
    13.         my_record.Open(CRecordset::snapshot, _T("select * from customer"));  
    14.   
    15.         if(my_record.IsBOF())  
    16.         {  
    17.             return;  
    18.         }  
    19.   
    20.         while(!my_record.IsEOF())  
    21.         {  
    22.             my_record.GetFieldValue((short)0, str);  
    23.             m_list_ctrl.InsertItem(count, str);  
    24.   
    25.             my_record.GetFieldValue(1, str);  
    26.             m_list_ctrl.SetItemText(count, 1, str);  
    27.               
    28.             my_record.MoveNext();  
    29.             count++;  
    30.         }  
    31.     }  
    32.     catch(CDBException* pe)  
    33.     {  
    34.         // The error code is in pe->m_nRetCode  
    35.         pe->ReportError();  
    36.         pe->Delete();  
    37.     }  
    38. }  


    我们可以看到,查询结果如下图:

    但是我们知道,设定查询范围怎么弄?需要where 子句,比如 :

    select * from customer where cust_id <= 200 and cust_id >= 100;

    但是使用了m_strFilter这个作为过滤规则的设定,就不能使用带上where了。


    七、我们可以设定排序规则,比如按照cust id排序,而且是逆序,这个操作就要借助于

    m_strSort

    了,也只要设定排序对象就是了:

    1. my_record.m_strFilter = _T("cust_id <= 200 and cust_id >= 100");  
    2.           
    3. my_record.m_strSort = _T("cust_id desc");  
    4. my_record.Open(CRecordset::snapshot, _T("select * from customer"));  

  • 和上面过滤的规则一样,sql语句是需要Order by子句的,如果使用了m_strSort之后,那么就不能有“order by”了,而这个语句:
  • my_record.m_strSort = _T("cust_id desc");

  • 就相当于, “order by cust_id desc” 子句了。
  • 修改后的消息响应函数就是这个样子的了:


    1. void Cmy_dbDlg::OnBnClickedGetAllItem()  
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     CRecordset my_record(&m_db_opr);  
    5.       
    6.     try  
    7.     {  
    8.         int count = 0;  
    9.         CString str;  
    10.   
    11.         my_record.m_strFilter = _T("cust_id <= 200 and cust_id >= 100");  
    12.         my_record.m_strSort = _T("cust_id desc");  
    13.   
    14.         my_record.Open(CRecordset::snapshot, _T("select * from customer"));  
    15.   
    16.         if(my_record.IsBOF())  
    17.         {  
    18.             return;  
    19.         }  
    20.   
    21.         while(!my_record.IsEOF())  
    22.         {  
    23.             my_record.GetFieldValue((short)0, str);  
    24.             m_list_ctrl.InsertItem(count, str);  
    25.   
    26.             my_record.GetFieldValue(1, str);  
    27.             m_list_ctrl.SetItemText(count, 1, str);  
    28.               
    29.             my_record.MoveNext();  
    30.             count++;  
    31.         }  
    32.     }  
    33.     catch(CDBException* pe)  
    34.     {  
    35.         // The error code is in pe->m_nRetCode  
    36.         pe->ReportError();  
    37.         pe->Delete();  
    38.     }  
    39. }  


    执行一下程序,自然就逆序打印了:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值