Ⅰ mfc 连接mysql ado和其他的区别
ODBC(Open DataBase Connection)开放式系统互连,是一种数据库访问协议,提供了访问数据库的API接口。基于ODBC的应用程序,对数据库操作不依赖于具体的DBMS,不直接与DBMS打交道,所有数据库操作由对应DBMS的ODBC驱动程序完成,即:系统中不需要安装DBMS系统,如SQL SERVER 2005,但必须有SQL SERVER 2005的ODBC驱动程序,然后在ODBC管理器中注册数据源后,就可以在应用程序中通过ODBC API访问该数据库。
ODBC数据库访问技术只适用于windows系统,因为需要在ODBC驱动程序管理器中进行数据源注册,而只有windows才集成了ODBC驱动程序管理器(“控制面板/管理工具/数据源”)。
ADO(ActiveX Data Object)具有跨系统平台特性,它直接对DBMS数据库进行操作,即系
统中必须有DBMS,但不需要驱动程序,不需要注册数据源,所以具有很好的可移植性。
VC++6中这两种技术所涉及到的MFC类:
MFC ODBC类包括CDatabase类 CRecordSet类 CRecoreView类 CFieldExchange类 CDBException类,具体说明请详见任何一本讲述数据库编程技术的参考书。
ADO是data object,即数据对象的意思,先看一些它包括哪些常用对象:
Command对象 Connection对象 Error对象 RecordSet对象 Field对象 Parameter对象,对应到MFC ADO类,主要有_ConnectionPtr _RecordsetPtr等类。
基于ODBC和ADO的VC++应用程序设计概述
习惯上建立基于文档视图的应用程序时,使用ODBC访问方法,创建应用程序时,需要在step 2 of 6 what database support would you like to include中选择"database view with file support"加载你要访问的数据库,如果在此选择None,后期编程载入数据库相当麻烦,请注意。(如果一个数据库中有多个表,可在此选择一个表进行类定义,默认类名为"工程名+Set",可在应用程序创建完成前最后一步进行改名;然后在编程时建立其他基于CRecordSet的数据库表类)
如果在step 2中设置访问的数据库和表,则在生成的应用程序框架的XXSet类中会自动加载对数据库和表的连接访问操作,当然你最好重新进行定义;系统只有在必要时才会调用GetDefaultConnection和GetDefaultSQL返回缺省的数据库连接定义和SQL语句。
当然也可以建立基于对话框的数据库访问应用程序,思路差不多,请读者自行参悟。
习惯上当建立基于对话框的应用程序时,选择使用ADO技术。对于小程序,在StdAfx.h中引入ADO动态连接库,在C***APP中应初始化COM库环境,创建和关闭ADO连接。对于大型项目,通过自定义的ADOConnection类封装数据库操作的各种接口。
Ⅱ mfc 数据库编程 (odbc)
没时间详细说 给你个例子 有时间晚上交流
qq 469392501
void CMemoDBSDlg::OnBtnDelMember()
{
// TODO: Add your control notification handler code here
//获取要删除的成员记录所在的行.
int nItem = m_listMember.GetNextItem(-1, LVNI_SELECTED);
if(nItem == -1){
AfxMessageBox("没有选择要删除的成员");
return;
}
//获取成员ID.
int id = atoi(m_listMember.GetItemText(nItem,0));
TRY{
CString sql;
//从数据库中删除记录.
sql.Format("DELETE member_tab "
"where member_id = %d",id);
TRACE(sql);
m_db.ExecuteSQL(sql);
//从列表控件中删除该记录.
m_listMember.DeleteItem(nItem);
}
CATCH(CDBException,ex)
{
AfxMessageBox (ex->m_strError);
AfxMessageBox (ex->m_strStateNativeOrigin);
}
AND_CATCH(CException,e)
{
TCHAR szError[100];
e->GetErrorMessage(szError,100);
AfxMessageBox (szError);
}
END_CATCH
}
void CMemoDBSDlg::OnBtnAddType()
{
// TODO: Add your control notification handler code here
//添加备注类型.
//初始化备注类型对话框实例.
CMemoTypeDlg dlg;
if(dlg.DoModal() == IDOK){
//从对话框中获取新添加的备注类型.
CString strName = dlg.m_strTypeName;
TRY{
CRecordset rs(&m_db);
//获取最大的类型ID值.
rs.Open(CRecordset::dynaset,
"Select max(TYPE_ID) from MEMO_TYPE_TAB");
//初始化新类型ID值为1.
int newTypeID = 1;
//如果数据库已经有类型记录,则新的类型ID为最大类型ID+1
if(!rs.IsEOF()) {
CDBVariant var;
rs.GetFieldValue((short)0, var, SQL_C_SLONG);
if (var.m_dwType != DBVT_NULL)
newTypeID = var.m_iVal + 1;
}
CString sql;
//向数据库中添加新的备忘录类型记录.
sql.Format("Insert into MEMO_TYPE_TAB(TYPE_ID,"
"TYPE_NAME) "
"VALUES("
"%d,'%s')",newTypeID,strName);
TRACE(sql);
m_db.ExecuteSQL(sql);
//向界面中添加记录行.
InsertMemoTypeItem(newTypeID,strName);
}
CATCH(CDBException,ex)
{
AfxMessageBox (ex->m_strError);
AfxMessageBox (ex->m_strStateNativeOrigin);
}
AND_CATCH(CException,e)
{
TCHAR szError[100];
e->GetErrorMessage(szError,100);
AfxMessageBox (szError);
}
END_CATCH
}
}
void CMemoDBSDlg::OnBtnModType()
{
// TODO: Add your control notification handler code here
//获取要修改的类型记录
int nItem = m_listType.GetNextItem(-1, LVNI_SELECTED);
//如果没有选择要修改的纪录,返回.
if(nItem == -1){
AfxMessageBox("没有选择要修改的类型");
return;
}
//获取要修改记录的ID和名称.
int id = atoi(m_listType.GetItemText(nItem,0));
CString name = m_listType.GetItemText(nItem,1);
//初始化备注类型对话框.
CMemoTypeDlg dlg;
//给对话框的变量赋值.
dlg.m_strTypeName = name;
if(dlg.DoModal() == IDOK){
//获取修改后的数据.
CString strName = dlg.m_strTypeName;
TRY{
CString sql;
//更新记录.
sql.Format("UPDATE MEMO_TYPE_TAB SET TYPE_NAME = '%s' "
" WHERE TYPE_ID = %d",strName,id);
TRACE(sql);
m_db.ExecuteSQL(sql);
//修改界面的值.
m_listType.SetItemText(nItem,1,strName);
}
CATCH(CDBException,ex)
{
AfxMessageBox (ex->m_strError);
AfxMessageBox (ex->m_strStateNativeOrigin);
}
AND_CATCH(CException,e)
{
TCHAR szError[100];
e->GetErrorMessage(szError,100);
AfxMessageBox (szError);
}
END_CATCH
}
}
void CMemoDBSDlg::OnBtnDelType()
{
// TODO: Add your control notification handler code here
//获取要删除的记录所在的行.
int nItem = m_listType.GetNextItem(-1, LVNI_SELECTED);
//如果没有选择,返回.
if(nItem == -1){
AfxMessageBox("没有选择要删除的类型");
return;
}
//获取要删除的类型ID
int id = atoi(m_listType.GetItemText(nItem,0));
TRY{
CString sql;
sql.Format("DELETE MEMO_TYPE_TAB "
"where TYPE_ID = %d",id);
TRACE(sql);
//删除类型记录
m_db.ExecuteSQL(sql);
//删除界面中的记录.
m_listType.DeleteItem(nItem);
}
CATCH(CDBException,ex)
{
AfxMessageBox (ex->m_strError);
AfxMessageBox (ex->m_strStateNativeOrigin);
}
AND_CATCH(CException,e)
{
TCHAR szError[100];
e->GetErrorMessage(szError,100);
AfxMessageBox (szError);
}
END_CATCH
}
void CMemoDBSDlg::OnBtnAddMemo()
{
// TODO: Add your control notification handler code here
//初始化备忘录信息对话框.
CMemoInfoDlg dlg;
//获取所有的家庭成员的名称.
for(int i = 0 ; i < m_listMember.GetItemCount() ; i++ )
dlg.m_strMemberArray.Add(m_listMember.GetItemText(i,1)) ;
//获取所有的类型信息.
for(i = 0 ; i < m_listType.GetItemCount() ; i++ )
dlg.m_strTypeArray.Add(m_listType.GetItemText(i,1)) ;
//打开对话框,添加新的记录.
if(dlg.DoModal() == IDOK){
//从对话框中获取记录值.
CString strName = dlg.m_strMember;
CString strType = dlg.m_strMemoType;
CString strHappenDate = dlg.m_oleDate.Format("%Y-%m-%d")
+ " " + dlg.m_oleTime.Format("%H:%M:%S");
CString strOperDate = COleDateTime::GetCurrentTime().Format("%Y-%m-%d %H:%M:%S");
int isEvent = dlg.m_isEvent;
CString strCost = dlg.m_strCost;
CString strMemo = dlg.m_strMemoInfo;
TRY{
CRecordset rs(&m_db);
CString sql;
//根据成员姓名获取成员ID值.
sql.Format("Select MEMBER_ID from MEMBER_TAB where "
"MEMBER_NAME = '%s'",strName);
rs.Open(CRecordset::dynaset,sql);
int memberID = 1;
if(!rs.IsEOF()) {
CDBVariant var;
rs.GetFieldValue((short)0, var, SQL_C_SLONG);
if (var.m_dwType != DBVT_NULL)
memberID = var.m_iVal;
}
rs.Close();
//根据备忘录类型获取备忘录类型ID.
sql.Format("Select TYPE_ID from MEMO_TYPE_TAB where "
"TYPE_NAME = '%s'",strType);
rs.Open(CRecordset::dynaset,sql);
int typeID = 1;
if(!rs.IsEOF()) {
CDBVariant var;
rs.GetFieldValue((short)0, var, SQL_C_SLONG);
if (var.m_dwType != DBVT_NULL)
typeID = var.m_iVal;
}
rs.Close();
//从SEQ_MEMO_ID序列中获取下一个值.这个值就是新的备忘录ID.
rs.Open(CRecordset::dynaset,
"Select max(MEMO_ID) from MEMO_INFO_TAB");
int memoID = 1;
if(!rs.IsEOF()) {
CDBVariant var;
rs.GetFieldValue((short)0, var, SQL_C_SLONG);
if (var.m_dwType != DBVT_NULL)
memoID = var.m_iVal+1;
}
sql.Format("Insert into MEMO_INFO_TAB(MEMO_ID,"
"MEMBER_ID,OPER_DATE,HAPPEN_DATE,"
"IS_BIGEVENT,EVENT_COST,TYPE_ID,MEMO_TEXT) "
"VALUES("
"%d,%d,'%s'"
",'%s',%d,'%s'"
",%d,'%s')",memoID,memberID,
strOperDate,strHappenDate,isEvent,strCost,typeID,strMemo);
TRACE(sql);
m_db.ExecuteSQL(sql);
//向界面中插入新的纪录.
InsertMemoInfoItem(memoID,strName,strOperDate,strHappenDate,isEvent,strCost,strType,strMemo) ;
}
CATCH(CDBException,ex)
{
AfxMessageBox (ex->m_strError);
AfxMessageBox (ex->m_strStateNativeOrigin);
}
AND_CATCH(CException,e)
{
TCHAR szError[100];
e->GetErrorMessage(szError,100);
AfxMessageBox (szError);
}
END_CATCH
}
}
Ⅲ 请教:MFC多线程数据库编程ado,数据库访问冲突。
用多线程同步技术,即一个线程将要取得数据区锁定,另一个线程此时不能存取此块的数据。
看看多线程同步的书。
例如:
void CCalibPage1::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
UpdateData();
m_nCounter++;
double r;
CSingleLock sLock(&(gpMainFrm->m_mutex));
sLock.Lock();//此处锁定
double v = gSpindleRevolution;
sLock.Unlock();//存取后释放。
if(m_bCalibStart)
{
r = m_CalibValue/v;
m_szTestValue0.Format("%f",v);
// m_szTestValue.Format("%f", (v * r));
m_szRatio.Format("%f", r);//
UpdateData(false);
}
else if(m_bVerify)
{
m_szTestValue.Format("%f",v*gcConfig.calib[PCL833_CHANNEL].ratio);
UpdateData(false);
}
if(m_nCounter > 30)
{
KillTimer(11);
m_bCalibStart = false;
m_bVerify = false;
MessageBox(_T("标定完成!"),_T("CNCTest"));
UpdateButtonStatus();
}
CPropertyPage::OnTimer(nIDEvent);
}
参见:
http://ke..com/view/2808915.htm
Ⅳ ADO+MFC数据库编程时,修改记录和插入记录的代码各条语句的意思
1. // 这个Open函数的第二个参数为什么和
答:你这里不都是一样的吗?
2.m_pRecordset->AddNew(); //为什么要这一句呢?是提示程序要添加新的记录了吗?
答:不是提示,这个是让表添加一个新行。
3.m_pRecordset->PutCollect("name", _variant_t(m_Name)); // 这里的PutCollect函数的作用是什么?
答:put 放入的意思。这里是把m_Name值放入表中的name字段中。
4.m_pRecordset->MoveFirst(); // 这一句和下面的Move有什么作用??
答:m_pRecordset表示记录集。MoveFirst移动指针到记录集中的第一行。
Move(cursel);移动到cursel)行。
5.m_pRecordset->PutCollect("age", atol(m_Age)); //为什么这里的强制转换是用atol,而不是用上面的_variant_t ???
答:因为在表中声明的age是long类型。放入数据时类型要一致。
Ⅳ 怎样在MFC编程中使用microsoft SQL server 2008建立数据库链接
为什么一定要选2008?安装sql server 2008需要首先将visual studio 2008升级到sp1,否则无法安装的。
建议使用sql server 2005。这个版本有完全版的--两张光盘的,第一张是服务器,第二张是managerment studio--也就是图形化操作数据库的界面。
你就装express版吧,这个版本有两张光盘的,没有的话就去电驴上下载。
连接数据库的话直接网络一下mfc ado编程。是在是漫天都是。
如果你不是很熟悉sql server,可以用ado读写mdb也就是access来练练手。对mfc而言,不管是access数据库,还是sql server,操作ado的语句都是一样的,不同点只是在数据库引擎关键字上。
Ⅵ 我在用MFC编程,如何写代码能修改access数据库中的数据
通过ado与access数据进行连接,然后执行sql 语句就可以操作数据库了。下面的链接是个简单例子:
http://dev.yesky.com/243/2230743.shtml
Ⅶ MFC编程用ADO连接数据库,执行查询语句后,如果返回0条记录有什么标志吗
if ((m_pRecordset->BOF)||(m_pRecordset->adoEOF))
{
// AfxMessageBox("没有记录");
return;
}
Ⅷ 关于编程和数据库!MFC(C++)
如果你的系统是在windows平台下的话,sqlserver肯定是不需要装驱动就能用的,当然如果你用数据库肯定需要安装相应的数据库软件,不然,根本没有库,你程序连接什么呢?是可以通过程序语言来控制数据库的写入,删除的,这个和标准的sql语句没有差别,你只需要会用就可以了,一般在windows平台线面访问数据的操作可以使用ado 和一些数据库控件,比如说datagrid
Ⅸ 关于数据库与Mfc的链接
数据库编程的思路都是一致的:打开数据库连接-》执行SQL语句-》获得查询结果-》关闭数据库连接,不同的数据库访问技术有不同的要求,比如用C API诘问MySql数据库的时候还得释放查询结果集。
ODBC访问数据库得配置数据源
配置ODBC数据源:打开控制面板下的“数据源”,弹出“ODBC数据源管理器”,选择DSN选项卡-》添加->你选择你的SQL Server选项,单击完成。如图然后你再按照向导提示添加。
代码中用ODBC访问数据库你得加上afxdb.h头文件,
用CDataBase 类连接数据库、CRecordSet类查询记录。
现在在VC访问数据库常用的是ADO访问,你可以找一下我前面的回答有ADO访问数据库的步骤。
CDataBase m_cODBCDb;
用CDataBase类的OpenEx()函数打开数据库连接。连接字符串你自己构造一下。
定义一个与上面数据库相关的查询对象
CRecordSet m_cODBCRec(&m_cODBCDb);
用这个查询对象的open方法就可以执行SQL语句与数据库交互了;
现在用VC、MFC访问数据库常用的技术是ADO,学学这个吧。难点、但很实用!
导入ADO库
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "adoEOF")
2、用导入的动态库的指针操作数据库.
打开数据库连接
_ConnectionPtr m_pConn; // 数据库连接指针
// 创建Conneciton对象
m_pConn.CreateInstance(_T("ADODB.Connection"));
用ConnectionPtr 的open方法m_pConn->Open(_bstr_t(m_sConn),
_T(""), _T(""), lOptions));
m_sConn为你连接数据库的信息,你应该按照你的要求打开数据库
然后你用打开的那个连接进行操作数据库。比如
_RecordsetPtr pRec = m_pConn->Execute(_bstr_t(pszSql), NULL, CmdText);
pszSql 就你要操作数据库的SQL语句。在这个SQL语句里你可以创建表、更新表等。
用ADO访问的时候要求初始他COM库和释放COM对象
// 初始化COM环境(库)
::CoInitialize(NULL);
//释放COM对象
::CoUninitialize();
Ⅹ mfc编程用的c++,然后想实现和Oracle的连接。
可以通过VC++ ADO访问ORACLE,以前做过,是肯定可行的。
看看下面这个连接对你有没有帮助:
http://www.cnblogs.com/doublesnke/archive/2011/07/19/2110328.html
lpszConnect="Provider=OraOLEDB.Oracle;User ID=system;Password=sys;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1,122)(PORT=1521)))(CONNECT_DATA=(SID=orcl)))";
这样的一长串连接字符串可以通过新建一个udl文件设置测试连接成功后,加载获得。