注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

倚楼听风雨

没有理想的人,永远也不能翱翔与蓝天白云之上~

 
 
 

日志

 
 

VC数据库访问技术之ODBC  

2008-01-11 00:22:12|  分类: 数据库 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

说明:

MFC 数据库访问方式有:ODBC,DAO,ADO

ODBC数据库编程:

1.创建数据源.

2.连接到数据源:

1)在Visual C++程序中使用刚才建立的数据源之前,还必须简历一个到数据源的连接.

在MFC中到数据源的连接封装在CDatabase类中,要使用CDatabase对象,在ODBC数据源管理器中数据源必须已经正确配置.

在同一个程序中可以使用多个数据源,或者多个连接对应同一个数据源.

连接函数:

virtual BOOL OpenEx(LPCTSTR lpszConnectionString,DWORD dwOptions=0);

    throw(CDBException,CMemoryException);

CDatabase m_db;

TRY{

    m_db.OpenEx("DSN=MySQL;UID=dbaccess;PWD=dbaccess",CDatabase::noOdbcDialog);

}

catch(CDBException ex)

{

    AfxMessageBox(ex->m_strError);

    AfxMessageBox(ex->m_strStateNativeOrigin);

}

AND_CATCH(CMemoryException *pEx)

{

    pEx->ReportError();

    AfxMessageBox("memory exception");

}

AND_CATCH(CMemoryException *pEx)

{

    pEx->ReprotError();

    AfxMessageBox("memory exception");

}

AND_CATCH(CException *e)

{

    TCHAR szError[100];

    e->GetErrorMessage(szError,100);

    AfxMessageBox(szError);

}

END_CATCH

连接一个已经配置好的数据源有一下方法:

CDatabase m_database;//声明对象

//测试库是否已经处于打开状态

if(!m_database.IsOpen())

{

    //Test 表示欲打开的数据源的名称

    if(!m_database.Open(_T("Test"))){

        Assert("不能打开到该数据源的连接!");

    }

    //......

    //关闭连接

    m_database.Close();

}

下面的代码段也可以打开一个数据源的连接,是更为完整的表述.

CDatabase *pDb=new CDatabase;

BOOL bStatus=FALSE;        //数据库是否成功打开标志

//设置连接超时属性为3秒钟

pDb->SetLoginTimeOut(3);

try

{

    bStatus=pDb->OpenEx("Text");

    if(bStatus)

        TRACE("\nDB Opened successfully.\n");

    else

        TRACE("\nOpen DSN failed.\n");

    }

catch(CMemoryException* pEx)//处理内存异常

{

    pEx->ReportError();

}

catch(CDBException*pDBEx)

{

    pDBEx->ReportError();

    TRACE("RetCode:%d strError:[%s] strState:[%s]\n",

            pDBEx->m_nRetCode,

            pDBEx->m_strError,

            pDBEx->m_strStateNativeOrigin);

}

pDB->Close();

2)创建结果集

在CRecordSet类中定义一个成员变量m_pDatabase,它是指向对象数据库类的指针.

用户可以通过一下方式将这个结果集对应到相应的数据源.

//m_database是上一小节已经声明过并连接到数据源的CDatabase对象.

CRecordset m_recordset1,m_recordset2;

m_recordset1.m_pDatabase=&m_database;    //m_recordset1复用m_database对象

m_recordset2.m_pDatabase=&m_database;    //m_recordset2复用m_database对象

3)添加和修改记录

增加记录可以使用AddNew()函数,要求数据库必须是以允许增加方式打开

m_recordset.AddNew();        //在表的末尾增加新的记录

...//输入新的字段值

m_recordset1.Update();        //将新记录存入数据库

m_recordset1.Requery();        //重建记录集

修改记录可以使用Edit()函数.如下所示:

//m_pSet是指向结果集m_recordset2的指针

m_pSet->Edit();                //修改当前记录

m_pSet->m_type="完成";        //修改当前记录的字段值

......

m_pSet->Update();            //将修改结果存入数据库

m_pSet->Requery();            //重建记录集

4)查询记录

查询记录可以使用CRecordSet::Open()和CRecordSet::Requery()成员函数.

在使用CRecordSet类对象之前,必须使用CRecordSet::Open()函数来获得有效的记录集.

一旦已经使用过CRecordset::Open()函数,那么下一次查询时就可以使用CRecordSet::Requery()函数了.

在调用CRecordSet::Open()函数时,如果已经将一个打开的CDatabase对象指针传给CRecordset类对象的m_pDatabase成员变量,那么就可以使用该数据库对象建立ODBC连接;否则(即m_pDatabase为空指针),就需要新建一个CDatabase类对象并使其与缺省的数据源相连,然后进行CRecordset类对象的初始化.缺省数据源由GetDefaultConnect()函数获得.

下面是几种查询方法,用户可以选择使用:

1.通过SQL语句打开记录集

SQL语句中包含查询条件

LPCTSTR strSQL;//strSQL是包含查询条件的SQL语句

m_recordset1.Open(strSQL);//m_recordset1是结果集的一个对象

2.使用m_strFilter和m_strSort

查询过程中也可以使用CRecordset的成员变量m_strFilter和m_strSort来执行条件查询和结果排序.

其中,m_strFilter为过滤字符串,存放的是SQL语句中WHERE以后的条件,而m_strSort为排序字符串,存放的是SQL语句中ORDER BY之后的字符串.下面是一个简单的例子:

//EMPLORYEE_AGE是参数

_itoa(EMPLOYEE_AGE,ch,8);        //EMPLOYEE_AGE是待查询记录的EMP_AGE值

m_recordset1.m_strFilter="EMP_AGE="+CString(ch);

m_recordset1.m_strSort="EMP_ID ASC";

m_recordset1.Requery();

对应的SQL语句为

SELECT * FROM PERSONNEL

WHERE EMP_AGE=EMPLOYEE_AGE

ORDER BY EMP_ID ASC;

3.参数查询

利用参数化可以更直观、更方便地完成条件查询任务.具体使用的方法如下:

(1)声明参变量

int EMPLOYEE_AGE;

CString strDept;

(2)在构造函数中初始化参变量

EMPLOYEE_AGE=24;

strDept=_T("Manufacture");        //Manufacture为员工所在部门

m_nParams=2;

(3)将列与参数进行绑定

pFX->setFieldType(CFieldExchage::param)

RFX_Int(pFX,_T("EMP_AGE"),EMPLOYEE_AGE);

RFX_Text(pFX,_T("DEPT_NAME"),strDept);

完成以上步骤后就可以利用参变量进行条件查询了:

m_recordset1->m_strFilter="EMP_AGE=? AND DEPT_NAME=?";

m_recordset1->EMP_AGE=24;

m_recordset1->DEPT_NAME="Manufacture";

m_recordset1->Requery();

参变量的值按绑定的顺序替换查询字符串中的"?"适配符

如果查询结果是多条记录,可以用CRecordSet类的函数MoveFirset()和MoveNext()函数来取得结果集中相对应的记录.

总结:

以上方法各有优劣,一般请看下SQL查询是最简单的一种,可以直接通过SQL语句得到查询结果,一般的应用开发仅用此方法即可.

5)删除记录

用Delete()函数即可,并且在调用Delete()函数后不需要再调用Update()函数.

m_pSet->Delete();

6)撤销操作

如果用户选择了增加或修改记录后希望放弃当前的操作,可以在调用Update()函数之前调用CRecordSet::Move(AFX_MOVE_REFRESH)来撤销增加或修改模式,并恢复在增加或修改模式之前的当前记录.其中参数AFX_MOVE_REFRESH的值为0.

7)记录集的其他操作

比如,从结果集中取得各个域的值,可以先声明一个CDBVariant对象,然后通过CRecordSet::GetFieldValue()函数来取值到CDBVariant对象,在根据值的类型吧CDBVariant的相应成员变量赋给所需要的变量.

m_recordset.GetFieldValue(2,varValue);        //2是域的位置,varValue是CDBVariant对象

int i=varVariant.m_iVal;                    //如果这个域对应的类型是整数

而CRecordSet::GetRecordCount()函数可以返回还未访问过的结果集里的记录数,可以用来判断结果集是否为空.

8)SQL语句的直接执行

通过CRecordSet类可以完成大多数的查询操作,但有时需要对数据库建立新表、删除表和建立新的字段等,这就需要用到CDatabase类直接执行SQL语句的机制.这可以用过CDatabase::ExecuteSQL()函数来完成.

//下面是为自己创建的类CTry编写执行SQL的函数MyExecuteSQL

BOOL CTry::MyExecuteSQL(const CString& strSQL)

{

    try

    {

        m_database->ExecuteSQL(strSQL);        //直接执行SQL语句

    }

    CATCH(CDBException*e)

    {

        CString strMsg;

        strMsg.LoadString(IDS_EXECUTE_SQL_FAILED);

        strMsg+=strSQL;

        return FALSE;

    }

    END_CATCH

    return TRUE;

}

  评论这张
 
阅读(619)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017