_variant_t类
Name.vt==VT_NULL 判断当前字段是否为空。
CONVERT(NVARCHAR(4000),名字)=’%s'” 转换一个字段的格式
数据库插入的语句
INSERT INTO 表格(字段1,字段2,字段3,字段4)VALUES(值1,值2,值3,值4)
例如:TempSearch1.Format(_T(“INSERT INTO 联系表(名字,卡号,电话号码,部门)VALUES(‘%s’,’%s’,’%s’,’%s’)”),name,card,number,apartment);
将联系表中插入一行,字段含有名字,卡号,电话号码,部门。注意使用连接对象的Execute的方法,这个方法的第一参数属于com接口类型其类型属于_bstr_t类,使用这个类就可以方便的把C++类型变量转换成COM中的变量了。TempSearch1属于c++中的CString类型。还有要注意的是,CString的Format方法中使用sql语句,要格式化的字符串,必须加上单引号,如果格式化字串的时候,不需要添加。
数据库查询的语句
select * from 表格 where 名字=某某
例如:select * from 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp)
从数据表中查找出名字等于Temp的字段。这里的CONVERT是做一个类型转换的功能。
CONVERT(data_type(length),data_to_be_converted,style)
data_type(length) 规定目标数据类型(带有可选的长度)。data_to_be_converted 含有需要转换的值。style 规定日期/时间的输出格式。
数据库更改的语句(主要是更改字段的内容)
UPDATE 表格 SET 字段1=值1,字段2=值2,字段3=值3,字段4=值4 where 字段1=值1
例如: TempSearch1.Format(_T(“UPDATE 联系表 SET 名字=’%s’,卡号=’%s’,电话号码=’%s’,部门=’%s’ where CONVERT(NVARCHAR(4000),名字)=’%s'”),dlg. m_al_name,dlg.
m_al_card,dlg.m_al_phone,dlg.m_al_apartment,Temp);
将联系表中名字temp的值做修改。可以修改里面的名字,卡号,电话号码,部门中的任意字段。
数据库的删除功语句
DELETE FROM 表格 where 字段1=值1
例如:TempSearch.Format(_T(“DELETE FROM 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp);
删除联系表中名字等于Temp,一行的数据
在数据库服务端,添加一个表格,然后在MFC中对数据库表格的数据做插入、删除和修改
ADO中的三个对象可以对数据库的数据做修改,这里只用用连接,和记录集对象
ADO属于OLEDB,OLEDB使用的com组件接口,所以使用ADO的时候要先初始化COM口,函数 CoInitialize(NULL);初始化后要记得卸载COM口,函数 CoUninitialize();
Connection对象是这三个对象的基础,它的主要作用是建立与数据库的连接,建立了与数据库的连接后,才能进行其它有关数据库的访问和操作。也就是说,使用ADO操作数据库,通常先用Connection对象的Open方法打开一个库连接,然后才能进行数据库的操作。操作完成后,要关闭这个库连接。
具体步骤如下:
第一步
需要囊括ADO的文件:#import “C:\Program Files\Common Files\System\ado\msado15.dll” no_namespace rename(“EOF”,”adoEOF”) 放在StdAfx.h中关于各种include的描述之后。这句话中#import的意思是引入,后面使用了rename为了避免类型库文件中的EOF和系统文件的EOF重名。
第二步
在修改初始化函数前,添加对话框,在新增两个对话框,添加和修改对话框,对话框上分别添加四个静态文本其caption改为姓名、卡号、电话号码、部门 ,和四个编辑框,分别为添加和修改对话框新增一个相关联的对话框类,方便后续添加和修改时用到这两个对话框,主对话框中也增加和修改一样的四个静态文本,五个编辑文本,五个按键,按键的值分别为add add1,update,search ,delete。
在OnInitDialog中初始化COM口,连接数据库。在初始化对话框之前连接上数据库,以后其他按键里面进行操作,就不必重复连接。定义m_pConnection 、m_pRecordset和 m_strConnect为dlg类的类成员函数,其变量类型分别为_ConnectionPtr、 _RecordsetPtr 和 _bstr_t
BOOL CdatabaseconnectDlg::OnInitDialog()
{……
CoInitialize(NULL);
m_strConnect= _bstr_t(“Driver=SQL Server;SERVER=172.16.1.251;Database=rita;uid=sa;pwd=sa”);
BOOL ret=0;
try
{
ret = m_pConnection.CreateInstance(_uuidof(Connection));///创建Connection实例
if(!ret)
{
m_pConnection->ConnectionTimeout = 3;
ret = m_pConnection->Open( m_strConnect,””, “”, adModeUnknown);
}
}
catch(_com_error e)///捕捉异常
{
CString errormessage;
errormessage.Format( _T(“连接数据库失败!\r\n错误信息:%s”),e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
}
CoUninitialize();
return TRUE;
}
在初始化对话框的时候,打开数据库连接
编写查询的函数,点击search选单,里面添代码如下:
{
// TODO: 在此添加控件通知处理程序代码
CString TempSearch;
CString Temp;
GetDlgItemText(IDC_SEARCH,Temp); //得到这个编辑框控件的值
TempSearch.Format(_T(“select * from 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp); 查找名字为Temp的所有行数据
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
try
{
m_pRecordset.CreateInstance(“ADODB.Recordset”);
m_pRecordset->Open( _bstr_t(TempSearch), //通过记录集的方法来查询数据集
_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
_variant_t Name,CardNumber,PhoneNumber,Department;
try
{
while(!m_pRecordset->rsEOF) //while循环在表中不停的查找要查找的字段
{Name=m_pRecordset->GetCollect( “名字”);
CardNumber=m_pRecordset->GetCollect(“卡号”);
PhoneNumber=m_pRecordset->GetCollect(“电话号码”);
Department=m_pRecordset->GetCollect(“部门”);
CString strtemp;
if(Name.vt!=VT_NULL) //判断数据库中值是否为空
{
strtemp.Format( _T(“%s”),Name.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_NAME, strtemp );
if(CardNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),CardNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_CARD, strtemp );
if(PhoneNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),PhoneNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_PHONE, strtemp );
if(Department.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),Department.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_APARTMENT, strtemp );
m_pRecordset->MoveNext();
}
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
m_pRecordset->Close();
m_pRecordset.Release();
}
调用字符集对象后一定要close和relea字符集
编写添加的函数,点击add选单,里面添代码如下:
这里添加数据库,通过点击按钮弹出对话框来实现。
void CdatabaseconnectDlg::OnBnClickedadd1()
{
CString TempSearch;
CString Temp;
CString local_name;
GetDlgItemText(IDC_SEARCH,Temp);
TempSearch.Format(_T(“select * from 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp);
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
try
{
m_pRecordset.CreateInstance(“ADODB.Recordset”);
m_pRecordset->Open( _bstr_t(TempSearch),
_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
_variant_t Name,CardNumber,PhoneNumber,Department;
try
{
while(!m_pRecordset->rsEOF)
{Name=m_pRecordset->GetCollect( “名字”);
CardNumber=m_pRecordset->GetCollect(“卡号”);
PhoneNumber=m_pRecordset->GetCollect(“电话号码”);
Department=m_pRecordset->GetCollect(“部门”);
CString strtemp;
if(Name.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),Name.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_NAME, strtemp );
local_name=strtemp;
if(CardNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),CardNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_CARD, strtemp );
if(PhoneNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),PhoneNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_PHONE, strtemp );
if(Department.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),Department.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_APARTMENT, strtemp );
m_pRecordset->MoveNext();
}
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
CString name;
CString card;
CString number;
CString apartment;
CString TempSearch1;
_variant_t RecordsAffected;
GetDlgItemText(IDC_NAME,name);
GetDlgItemText(IDC_CARD,card);
GetDlgItemText(IDC_PHONE,number);
GetDlgItemText(IDC_APARTMENT,apartment);
TESTDLG dlg;
CString TempSearch2;
_variant_t RecordsAffected1;
if(dlg.DoModal()!=IDOK) //判断是否获得图片
{
return ;
}
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
if(local_name==dlg.m_name1) //将查找的值与对话框中的值进行比较,如果相同就弹出提示消息
{
AfxMessageBox(_T(“名字重复,不许添加”));
return;
}
try
{
TempSearch2.Format(_T(“INSERT INTO 联系表(名字,卡号,电话号码,部门)VALUES(‘%s’,’%s’,’%s’,’%s’)”),dlg.m_name1,dlg.m_card1,dlg.m_phone1,dlg.m_apartment1);
bstr_t strCmd;
strCmd=( bstr_t)TempSearch2;
m_pConnection->Execute(strCmd,&RecordsAffected1,adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
m_pRecordset->Close();
m_pRecordset.Release();
}
首先要先查找当前数据库里面的所有信息,如果检查到当前数据库里面名字字段和添加的字段相同就不允许添加。
之前新建了增加了添加对话框的类,添加类的变量分别于对话框中的四个控件相关联,控件的值相关联,其值为m_name1,m_card1,m_phone1,m_apartment1,当点击添加按钮后,弹出添加的对话框,在对话框上的四个编辑框分别输入值后,使用sql中的插入语句将其值写入到数据库表格中,在dlg.DoModal==IDOK是将添加的对话框弹出,如果在这个对话框中点击确定按钮的话,对话框销毁,再去用GetDlgItemText函数,读不到对话框控件上的值,所以将控件的值与对话框类关联起来,当按对话框退出后,与对话框相关联的类的成员变量的值不会被销毁,用SQL的插入语句,将其值写入到数据库中。
编写修改的函数,点击update选单,里面添代码如下:
void CdatabaseconnectDlg::OnBnClickedUpdate()
{
// TODO: 在此添加控件通知处理程序代码
CString TempSearch;
_variant_t RecordsAffected;
CString name;
CString card;
CString number;
CString apartment;
CString Temp;
GetDlgItemText(IDC_SEARCH,Temp);
TempSearch.Format(_T(“select * from 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp);
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
try
{
m_pRecordset.CreateInstance(“ADODB.Recordset”);
m_pRecordset->Open( _bstr_t(TempSearch),
_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,
adLockOptimistic,
adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
_variant_t Name,CardNumber,PhoneNumber,Department;
try
{
while(!m_pRecordset->rsEOF)
{Name=m_pRecordset->GetCollect( “名字”);
CardNumber=m_pRecordset->GetCollect(“卡号”);
PhoneNumber=m_pRecordset->GetCollect(“电话号码”);
Department=m_pRecordset->GetCollect(“部门”);
CString strtemp;
if(Name.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),Name.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_NAME, strtemp );
name = strtemp;
if(CardNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),CardNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_CARD, strtemp );
card = strtemp;
if(PhoneNumber.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),PhoneNumber.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_PHONE, strtemp );
number= strtemp;
if(Department.vt!=VT_NULL)
{
strtemp.Format( _T(“%s”),Department.lVal);
}
else
{
strtemp.Format( _T(“”),Name.lVal);
}
SetDlgItemText(IDC_APARTMENT, strtemp );
apartment= strtemp;
m_pRecordset->MoveNext();
}
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
ALTER dlg;
dlg.m_al_name=name;
dlg. m_al_card=card;
dlg.m_al_phone=number;
dlg.m_al_apartment=apartment;
CString
TempSearch1;
if(dlg.DoModal()==IDOK) //判断是否获得图片
{ TempSearch1.Format(_T(“UPDATE 联系表SET 名字=’%s’,卡号=’%s’,电话号码=’%s’,部门=’%s’ where CONVERT(NVARCHAR(4000),名字)=’%s'”),dlg. m_al_name,dlg. m_al_card,dlg.m_al_phone,dlg.m_al_apartment,Temp);
}
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
try
{
_bstr_t strCmd=TempSearch1;
m_pConnection->Execute(strCmd,&RecordsAffected,adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
m_pRecordset->Close();
m_pRecordset.Release();
}
和添加函数一样要注意当一个对话框销毁后,就不能读到其对话框控件的值,只有在这之前将对话框控件的值与类的成员变量相关联。
编写删除的函数,点击deltete选单,里面添代码如下:
void CdatabaseconnectDlg::OnBnClickedDel()
{
// TODO: 在此添加控件通知处理程序代码
_variant_t RecordsAffected;
CString TempSearch;
CString Temp;
GetDlgItemText(IDC_SEARCH,Temp);
if (!m_pConnection->State )
{
AfxMessageBox(_T(“请先连接数据库”));///显示错误信息
}
try
{
TempSearch.Format(_T(“DELETE FROM 联系表 where CONVERT(NVARCHAR(4000),名字)=’%s'”), Temp);
bstr_t strCmd;
strCmd=( bstr_t)TempSearch;
m_pConnection->Execute(strCmd,&RecordsAffected,adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
SetDlgItemText(IDC_NAME,NULL);
SetDlgItemText(IDC_CARD,NULL);
SetDlgItemText(IDC_PHONE,NULL);
SetDlgItemText(IDC_APARTMENT,NULL);
}
还有一个值得注意的地方时,查找的时候字段一段要和新建表格的字段相匹配。strtemp.Format( _T(“%s”),CardNumber.lVal); 这个一定是%s,新建表格的时候,这个字段为nchar类型。不能谢伟%d.不能再编辑框中显示就会出问题。