zoukankan      html  css  js  c++  java
  • ADO+MFC数据库编程常用语句

    设在OnInitDialog()函数中,已经完成了初始化COM,创建ADO连接等操作,即

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. // 初始化COM,创建ADO连接等操作  
    2.     if (!AfxOleInit()) {  
    3.         AfxMessageBox("OLE/COM初始化失败");  
    4.         return FALSE;  
    5. }  
    6.     HRESULT hr;  
    7.     try  
    8.     {  
    9.     //  hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象  
    10.         hr =    m_pConnection.CreateInstance(__uuidof(Connection));  
    11.         if(SUCCEEDED(hr))  
    12.         {  
    13.             hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test1.mdb","","",adModeUnknown);///连接  
    14.   
    15.         //  hr = m_pConnection->Open("Provider=SQLOLEDB;server=(local);UID=sa;PWD=123;database=test1","","",adModeUnknown);  
    16.   
    17.         }  
    18.     }  
    19.     catch(_com_error e)///捕捉异常  
    20.     {  
    21.         CString errormessage;  
    22.         errormessage.Format("连接数据库失败! 错误信息:%s",e.ErrorMessage());  
    23.         AfxMessageBox(errormessage);///显示错误信息  
    24.     }  



    一、点击”读取按钮“,从数据库中读取数据,在界面上显示,有三种方法:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void CMyLinkMdbDlg::OnReadAccess()   
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.   /*******************以下提供了3种形式方法执行SQL命令*****************/  
    5.   
    6.     /*  ***********第一种  用Execute 执行SQL命令**********    
    7.  
    8.     try 
    9.     { 
    10.     m_pRecordset.CreateInstance("ADODB.Recordset"); 
    11.     _bstr_t strCmd="SELECT * FROM [user]"; 
    12.     m_pRecordset=m_pConnection->Execute(strCmd,&RecordsAffected,adCmdText); 
    13.     } 
    14.     catch(_com_error *e) 
    15.     { 
    16.         AfxMessageBox(e->Description()); 
    17.     } 
    18.  */  
    19.   
    20.   
    21.      /************第二种   用command命令操作SQL语句************ 
    22.         m_pCommand.CreateInstance("ADODB.Command"); 
    23.         _variant_t vNULL; 
    24.         vNULL.vt = VT_ERROR; 
    25.         vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数 
    26.         m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它 
    27.         m_pCommand->CommandText = "SELECT * FROM [user]";///命令字串 
    28.         m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集 
    29.      */  
    30.   
    31.    /**************第三种   直接用open执行SQL语句 *************/  
    32.     m_pRecordset.CreateInstance(__uuidof(Recordset));  
    33.     try  
    34.     {  
    35.         m_pRecordset->CursorLocation   =   adUseClient;          //若需要排序的话必须要  
    36.         m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  
    37.             _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  
    38.             adOpenDynamic,  
    39.             adLockOptimistic,  
    40.             adCmdText);  
    41.         m_pRecordset->Sort   =   "id   asc";          //按照id升序排序  
    42.   
    43.     }  
    44.     catch(_com_error *e)  
    45.     {  
    46.         AfxMessageBox(e->ErrorMessage());  
    47.     }  
    48.     
    49.   
    50.   
    51.   
    52.   
    53.     _variant_t vID,vName,vAge;            
    54.     // 清空列表框  
    55.     m_DataList.ResetContent();  
    56.     m_DataList.SetCurSel(0);  
    57.     vName=vAge="";  
    58.     // 在ADO操作中建议语句中要常用try...catch()来捕获错误信息,  
    59.     // 因为它有时会经常出现一些想不到的错误。jingzhou xu  
    60.   
    61.     try  
    62.     {  
    63.         if(!m_pRecordset->BOF)  
    64.             m_pRecordset->MoveFirst();  
    65.         else  
    66.         {  
    67.             AfxMessageBox("表内数据为空");  
    68.             return;  
    69.         }  
    70.             CString strtemp;  
    71.             while (!m_pRecordset->adoEOF)  
    72.             {  
    73.                 strtemp = "";  
    74.                 vID=m_pRecordset->GetCollect(_variant_t((long)0));  
    75.                 //取得第1列的值,从0开始计数,你也可以直接列出列的名称,如下一行  
    76.                 vName=m_pRecordset->GetCollect("name");  
    77.                 vAge=m_pRecordset->GetCollect("age");  
    78.                   
    79.               
    80.                 if(vID.vt != VT_NULL)  
    81.                 {  
    82.                     strtemp.Format("%d",vID.lVal);  
    83.                 }  
    84.                   
    85.                 if(vName.vt != VT_NULL)  
    86.                 {  
    87.                     strtemp += "             ";  
    88.                     strtemp += (LPCTSTR)(_bstr_t)vName;  
    89.                 }  
    90.                   
    91.                 if(vAge.vt != VT_NULL)  
    92.                 {  
    93.                     strtemp += "             ";  
    94.                     strtemp += (LPCTSTR)(_bstr_t)vAge;  
    95.                 }             
    96.                 m_DataList.AddString(strtemp);    
    97.                 UpdateData(FALSE);        
    98.                 m_pRecordset->MoveNext();  
    99.             }  
    100.             m_DataList.SetCurSel(0);  
    101.             OnSelchangeData();  
    102.           
    103.     }  
    104.     catch(_com_error *e)  
    105.     {  
    106.         AfxMessageBox(e->ErrorMessage());  
    107.     }  
    108.     m_pRecordset->Close();  
    109.     m_pRecordset=NULL;  
    110.   
    111. }  



    二、插入数据

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void CMyLinkMdbDlg::OnInsert()   
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     UpdateData(TRUE);  
    5.     if (m_Age == "" || m_Name == "")  
    6.     {  
    7.         AfxMessageBox("输入不能为空");  
    8.         return;  
    9.     }  
    10.   
    11.     m_pRecordset.CreateInstance(__uuidof(Recordset));  
    12.     try  
    13.     {  
    14.         m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  
    15.             _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  
    16.             adOpenDynamic,  
    17.             adLockOptimistic,  
    18.             adCmdText);  
    19.         m_pRecordset->AddNew();                         //用这种方法添加数据就必须用open 语句执行SQL语句  
    20.         m_pRecordset->PutCollect("name", _variant_t(m_Name));  
    21.         m_pRecordset->PutCollect("age", atol(m_Age));  
    22.         m_pRecordset->Update();  
    23.         m_pRecordset->Close();  
    24.         AfxMessageBox("插入成功!");  
    25.         OnReadAccess();  
    26.   
    27.     }  
    28.     catch(_com_error *e)  
    29.     {  
    30.         AfxMessageBox(e->ErrorMessage());  
    31.     }  
    32.   
    33.     m_pRecordset=NULL;  
    34.   
    35. }  


    三、修改数据

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void CMyLinkMdbDlg::OnModify()   
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     int cursel = m_DataList.GetCurSel();         //得到当前所选记录的索引  
    5.   
    6.     UpdateData(TRUE);  
    7.     if (m_Age == "" || m_Name == "")  
    8.     {  
    9.         AfxMessageBox("输入不能为空");  
    10.         return;  
    11.     }  
    12.     m_pRecordset.CreateInstance(__uuidof(Recordset));  
    13.     try  
    14.     {  
    15.         m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  
    16.             _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  
    17.             adOpenDynamic,  
    18.             adLockOptimistic,  
    19.             adCmdText);  
    20.         m_pRecordset->MoveFirst();  
    21.         m_pRecordset->Move(cursel);  
    22.         m_pRecordset->PutCollect("name", _variant_t(m_Name));  
    23.         m_pRecordset->PutCollect("age", atol(m_Age));  
    24.         m_pRecordset->Update();  
    25.         m_pRecordset->Close();  
    26.         OnReadAccess();                 //修改后需重新读取数据库  
    27.   
    28.         m_DataList.SetCurSel(cursel);       //修改后指针仍旧指向刚修改的记录  
    29.           
    30.     }  
    31.     catch(_com_error *e)  
    32.     {  
    33.         AfxMessageBox(e->ErrorMessage());  
    34.     }  
    35.       
    36.     m_pRecordset=NULL;  
    37. }  


    四、删除数据

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void CMyLinkMdbDlg::OnDelete()   
    2. {  
    3.     // TODO: Add your control notification handler code here  
    4.     int cursel = m_DataList.GetCurSel();         //得到当前所选记录的索引  
    5.       
    6.     m_pRecordset.CreateInstance(__uuidof(Recordset));  
    7.     try  
    8.     {  
    9.         m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  
    10.             _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  
    11.             adOpenDynamic,  
    12.             adLockOptimistic,  
    13.             adCmdText);  
    14.         m_pRecordset->MoveFirst();  
    15.         m_pRecordset->Move(cursel);  
    16.         m_pRecordset->Delete(adAffectCurrent);             //参数adAffectCurrent为删除当前记录  
    17.         m_pRecordset->Update();  
    18.         m_pRecordset->Close();  
    19.         OnReadAccess();                 //修改后需重新读取数据库  
    20.           
    21.         m_DataList.SetCurSel(cursel - 1);  
    22.           
    23.     }  
    24.     catch(_com_error *e)  
    25.     {  
    26.         AfxMessageBox(e->ErrorMessage());  
    27.     }  
    28.       
    29.     m_pRecordset=NULL;  
    30. }  

    以上四部分完成了数据库最常用的增、删、改、查功能~

    先在程序初始化函数中完成COM的初始化和数据库的连接,再在每一个增删改查的函数中,创建记录集

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. m_pRecordset  

    用m_pRecordset调用Open函数,打开数据库,获取数据记录集,

    再用m_pRecordset就可以灵活调用数据库了~~

    在读取数据库内容函数中:

    (1)

    if(!m_pRecordset->BOF)
    m_pRecordset->MoveFirst();

    还有

    while (!m_pRecordset->adoEOF)

    {

    ……

    m_pRecordset->MoveNext();

    ……

    }

    这里就涉及到BOF和EOF的作用,其实上面的 if 和 while 的写法基本上就是固定的了,在不同的应用程序里都差不多~~

    简单的说,

    ~使用 BOF 和 EOF(adoEOF) 属性可确定 Recordset 对象是否包含记录,或者从一个记录移动到另一个记录时是否超出 Recordset 对象的限制。
    ~如果当前记录位于第一个记录之前,BOF 属性将返回 True (-1),如果当前记录为第一个记录或位于其后则将返回 False (0)。 
    ~如果当前记录位于 Recordset 对象的最后一个记录之后 EOF(adoEOF)  属性将返回 True,而当前记录为 Recordset 对象的最后一个记录或位于其前,则将返回 False。
    ~如果 BOF 或 EOF (adoEOF) 属性为 True,则没有当前记录

    也即是说,if(!m_pRecordset->BOF)
    m_pRecordset->MoveFirst();

    这里的作用就是,如果表内数据不为空,就把记录集指针移动到第一条记录(MoveFirst),(移动指针到记录集中的第一行)

    现在就可以用m_pRecordset调用其他函数对数据库里的内容进行操作了~~

    在while循环中,易看出,当我们读取记录集中的数据时,只要没有读到末尾,那么,一直调用m_pRecordset->MoveNext(); 让指针下移~~

    (2)在”插入数据库“部分,有以下代码:

    m_pRecordset->AddNew();                         //用这种方法添加数据就必须用open 语句执行SQL语句
    m_pRecordset->PutCollect("name", _variant_t(m_Name));
    m_pRecordset->PutCollect("age", atol(m_Age));
    m_pRecordset->Update();
          m_pRecordset->Close();

    AddNew 这个是让表添加一个新行
    再执行下面两个Putcollect ,
    put 放入的意思。这里是把m_Name值放入表中的name字段中;m_Age放入age 字段中~~
    Update是更新数据记录集
    Close是关闭数据记录集~
     
    (3)在”修改数据“部分,有下列代码:
    		m_pRecordset->MoveFirst();
    		m_pRecordset->Move(cursel);
    		m_pRecordset->PutCollect("name", _variant_t(m_Name));
    		m_pRecordset->PutCollect("age", atol(m_Age));
    		m_pRecordset->Update();
    		m_pRecordset->Close();
    MoveFirst 移动指针到记录集的第一行(即,设置默认情况下,指针在第一行)
    Move(cursel),移动到cursel行,即移动到光标指向的位置 (光标的位置要响应ListBox的单击响应函数)
    由于记录集指针在光标指向的位置,所以再执行下面两个PutCollect 函数时,再往该行中写入数据,相当于把原来该行的数据覆盖了~~就能起到修改的作用~~
  • 相关阅读:
    满屏的宽高纯CSS布局
    截屏上传插件开发流程
    COM ACTIVEX 中的BSTR 类型与其它类型转换
    线程中访问控件
    OOP三言两语
    通过iframe上传
    历年作品点评
    每周进度及工作量统计2016090820160915
    英文词频统计的java实现方法
    四人小组项目——连连看
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/5128662.html
Copyright © 2011-2022 走看看