ODBC

作者: downdemo | 来源:发表于2018-03-19 10:24 被阅读14次

几个常用类

  • afxdb.h
    • CDBException:CException 171-197
    • CDatabase:CObject 204-318
    • CFieldExchange 322-401
    • CRecordset:CObject 556-957
    • CDBVariant 1025-1056
    • CRecordView:CFormView 1061-1101
  • 1.0Set.cpp
    • CMy10Set:CRecordset
    • GetDefaultConnect()
    • GetDefaultSQL()
    • DoFieldExchange // RFX
    • AssertValid()
    • Dump()

构建数据源

  • 控制面板-管理工具-ODBC数据源64位
  • 建立ODBC数据源-连接数据库-选择和处理记录-数据库应用程序中的文档与视图
  • ODBC数据源-系统DSN-添加Access-数据源名My_DataSource-确定
  • 访问数据要连接数据源,连接封装到CDatabase类中
  • 连接后可以
    • 构造CRecordset派生类对象,从数据库中读取相应记录,保存在CRecordset派生类中
    • 管理事务
    • 执行SQL
  • 要正确使用CDatabase必须在ODBC数据源控制台中正确注册,同意程序可以有多个数据源,对应多个CDatabase对象,也可以用多个CDatabase对象连接同一数据源
  • CRecordset一般要派生出一个新子类,在CRecordset派生类中的数据对应数据库中相应的行
  • 用户要重载CRecordset类中的GetDefaultSQL函数来返回使用的表的名字
  • CRecordset对象负责定制SQL、在数据库中移动记录指针、增删改查,不需要时就要释放CRecordset对象
  • 视图文档结构:视图显示数据,文档对象(有多个)存取不同的数据,视图还负责和文档的数据交换和更新。有时这样的结构多余,如当只操作一个数据源中的一个数据库,数据放在视图类中就行了
  • 新建一个表My_Access_DB,作者、出版社、价格,内容自填
  • 新建MFC-单文档-文件支持+ODBC+选择数据源-新建DSN(.mdb)-浏览位置,取名My_1.0,完成-进入ODBC Access安装-数据库:选择-选择之前建好的表

关联编辑框控件和数据

  • 建DIALOG,4个Static Text+4个Edit Control,关联完即可显示
  • 1.0set.h
    • CMy10Set:CRecordset
      • long m_ID
      • CStringW column1
      • CStringW column2
      • double column3
      • GetDefaultConnect()
      • GetDefaultSQL()
      • DoFieldExchange()
      • AssertValid()
      • Dump()
  • 1.0View.cpp
    • CMy10View:CRecordView
    • DoDataExchange() // 关联编辑框控件和数据库字段,使用下面的函数关联
      • DDX_FieldText(pDX, IDC_EDIT1, m_pSet->m_ID, m_pSet)
      • DDX_FieldText(pDX, IDC_EDIT2, m_pSet->column1, m_pSet)_
    • PreCreateWindow()
    • OnInitialUpdate()
    • OnFilePrintPreview()
    • OnPreparePrinting()
    • OnBeginPrinting()
    • OnEndPrinting()
    • OnRButtonUp()
    • OnContextMenu()
    • AssertValid()
    • Dump()
    • GetDocument()
    • OnGetRecordset()

菜单项更新和删除

  • Resource View-1.0.rc-Menu-IDR_MAINFRAME
  • 加入三个菜单项,分别为删除、更新、清空,为其分配ID如下,并右键添加Event Handler
    • ID_DELETE_RECORD
    • ID_UPDATE_RECORD
    • ID_CLEAR_DOMAIN
  • 第一个COMMAMD
void CMy10View::OnDeleteRecord()
{
    // TODO: Add your command handler code here
    CRecordsetStatus m_cStatus;
    try{ m_pSet->Delete();  }
    catch (CDBException* m_pEx)
    {
        AfxMessageBox(m_pEx->m_strError);
        m_pEx->Delete();
        m_pSet->MoveFirst(); // 失败则将记录指针移到开头
        UpdateData(FALSE);
        return;
    }

    m_pSet->GetStatus(m_cStatus);
    if (m_cStatus.m_lCurrentRecord == 0)
        m_pSet->MoveFirst();
    else
        m_pSet->MoveNext();
    UpdateData(FALSE);
}
  • 第一个UPDATE_COMMAND_UI
void CMy10View::OnUpdateDeleteRecord(CCmdUI *pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(!m_pSet->IsEOF());
}
  • 第二个COMMAND
void CMy10View::OnUpdateRecord()
{
    // TODO: Add your command handler code here
    m_pSet->Edit();
    UpdateData(TRUE);
    if (m_pSet->CanUpdate()) // 记录可更新则返回非零值
        m_pSet->Update();
}
  • 第二个UPDATE_COMMAND_UI
void CMy10View::OnUpdateUpdateRecord(CCmdUI *pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->Enable(!m_pSet->IsEOF());
}
  • 第三个COMMAND
void CMy10View::OnClearDomain()
{
    // TODO: Add your command handler code here
    m_pSet->SetFieldNull(NULL);
    UpdateData(FALSE);
}

重载OnMove

  • Class View-右键CMy10View,Class Wizard-Virtual Functions-双击左边的OnMove会出现到右边的重写虚函数的列表中,Edit Code
BOOL CMy10View::OnMove(UINT nIDMoveCommand)
{
    // TODO: Add your specialized code here and/or call the base class
    switch (nIDMoveCommand)
    {
        case ID_RECORD_PREV:
            if (!m_pSet->IsBOF())
                m_pSet->MovePrev();
            break;
        case ID_RECORD_FIRST:
            m_pSet->MoveFirst();
            break;
        case ID_RECORD_NEXT:
            if (!m_pSet->IsEOF())
                m_pSet->MoveNext();
            break;
        case ID_RECORD_LAST:
            m_pSet->MoveLast();
            break;
        default:
            ASSERT(FALSE);
    }
    UpdateData(FALSE);
    return CRecordView::OnMove(nIDMoveCommand);
}

菜单项添加

  • 给菜单项加一个选项,ID设为ID_ADD_RECORD
  • 在class view中,右键Set类,选择Add-Add Functions
  • 添加函数名为GetMaxID
  • 在xxxSet.cpp中即可看到添加的函数,修改如下
int CMy10Set::GetMaxID()
{
    MoveLast(); // 移到最后一条记录
    return m_ID;
}
  • 右键新的菜单项,Event Handler添加COMMAND消息
void CMy10View::OnAddRecord()
{
    // TODO: Add your command handler code here
    CRecordset* pSet = OnGetRecordset(); // 获取指向数据库的指针
    if (pSet->CanUpdate() && !pSet->IsDeleted())
    {
        pSet->Edit();
        if (!UpdateData()) return;
        pSet->Update();
    }
    long m_INewID = m_pSet->GetMaxID() + 1; // 获取新ID值
    m_pSet->AddNew(); // 添加一个新记录
    m_pSet->m_ID = m_INewID;
    m_pSet->Update(); // 保存新记录
    m_pSet->Requery(); // 刷新数据库
    m_pSet->MoveLast();
    UpdateData(FALSE); // 更新表单
}

菜单项浏览和排序

  • 新建一个Dialog,ID改为IDD_MOVE_RECORD,右键Add Class,类名为CMoveToRecord,在MoveToRecord.h中#include "resource.h"
  • 添加一个Static Text和Edit Control,Edit Control的ID设置为IDC_RECORD_ID
  • 给Edit Control添加一个变量m_RecordID,Category设置为Value,类型设置为long


  • 增加菜单项如下,ID设置为ID_MOVEToRecord


  • 添加COMMAND消息CMy10View::OnMovetorecord(),在视图类1.0View.cpp中#include "MoveToRecord.h"

  • 打开Resource View-Tool Bar-IDR_MAINFRAME,添加一个按钮,点击上方的A(Text Tool)输入字符为M,ID选择为ID_MOVEToRecord

  • 接着响应前一步的COMMAND消息
void CMy10View::OnMovetorecord()
{
    // TODO: Add your command handler code here
    CMoveToRecord dlgMoveTo;
    if (dlgMoveTo.DoModal() == IDOK)
    {
        CRecordset *pSet = OnGetRecordset();
        pSet->SetAbsolutePosition(dlgMoveTo.m_RecordID);
        UpdateData(FALSE);
    }
}
  • 此时运行就可以使用移动到某条记录的功能了,接下来是排序。在CRecordSet和其派生类中有一个m_strSort成员,决定了记录的排序。在菜单项中添加菜单项“按价格排序”,ID设为ID_SORT_PRICE,映射COMMAND消息处理函数OnSortPrice(),之后运行就是按价格递增的排序了
void CMy10View::OnSortPrice()
{
    // TODO: Add your command handler code here
    // TODO: Add your command handler code here
    m_pSet->Close(); // 关闭数据库
    m_pSet->m_strSort = "价格";
    m_pSet->Open();
    UpdateData(FALSE); // 更新已排序过的记录
}

相关文章

网友评论

      本文标题:ODBC

      本文链接:https://www.haomeiwen.com/subject/wieuqftx.html