报刊订阅系统.docx
- 文档编号:18605662
- 上传时间:2023-08-20
- 格式:DOCX
- 页数:24
- 大小:257.13KB
报刊订阅系统.docx
《报刊订阅系统.docx》由会员分享,可在线阅读,更多相关《报刊订阅系统.docx(24页珍藏版)》请在冰点文库上搜索。
报刊订阅系统
数据库课程设计
实习报告
院系:
XXXXXXXXXXXXXXX
姓名:
XXX
学号:
XXXXXXXX
二零零七年一月十四日
数据库课程设计
一.实验目的:
加深对数据库系统、软件工程、程序设计语言的理论知识的理解和应用水平;
在理论和实验教学基础上进一步巩固已学基本理论及应用知识并加以综合提高;
学会将知识应用于实际的方法,提高分析和解决问题的能力,增强动手能力;
为毕业设计和以后工作打下必要基础。
二.课程设计任务
设计一个订户订阅报刊的应用系统。
涉及订单、订户、报刊目录及投递卡信息。
1、系统语义描述如下:
●一个订户可订多种报刊;一种报刊可被多个用户订阅;订单只能订阅现有报刊目录内容;
●一张投递卡可包含对多个订户的订单的投递信息;
2、系统功能包括:
●订户管理:
订户增加、修改、删除;
●目录管理:
目录增加、删除、修改;
●订单管理:
完成订户订阅数据的管理;
●订单查询:
按订户查询订单详细情况;
●统计查询:
按报刊目录统计各类报刊的订阅数量及金额
3、实现内容
●创建数据库的结构
●创建各基本表的结构
●编制系统各功能模块,完成数据的管理(增、删、改)及统计查询。
三.数据库系统设计
1.设计E-R图
2.设计相应的关系模型,确定数据库结构
根据基础数据建立名为“报刊”的数据库,并建立三个关系表:
订单表CUS_ORDER、用户表CUSTOMER、报刊表NMTABLE,各表结构及数据结构如下:
(1)CUS_ORDER表:
(2)CUSTOMER表:
(3)报刊表NMTABLE:
3.数据库范式分析
由于此数据库不存在传递依赖和部分依赖,所以该数据库系统属于第三范式。
4.设计应用系统的系统结构图,确定系统功能:
程序由MFC编写,编译平台为MicrosoftVisualStudio.NET2003。
流程图如下:
5.设计关系的主码约束、外码约束和使用CHECK实现完整性控制:
6.应用程序编写
(1)连结数据库
try
{
HRESULThr;
//创建Connection对象
hr=m_pConnection.CreateInstance("ADODB.Connection");
if(SUCCEEDED(hr))
{
//连接数据库
hr=m_pConnection->Open("provider=SQLOLEDB.1;DataSource=127.0.0.1;userID=sa;Password=123456;InitialCatalog=报刊","","",adModeUnknown);
//MessageBox(0,_T("连结成功"),_T("成功"),0);
}
else
{
MessageBox(NULL,"创建ADO对象失败","失败",MB_OK);
returnfalse;
}
}
catch(...)
{
MessageBox(NULL,"连接数据库失败,请确定数据库是否启动且账号是否正确!
",_T("连接数据库失败"),MB_OK);
returnfalse;
}
程序采用COM接口连结数据库,所以先初始化OLE组件,再创建Connection实例,如果创建成功,就尝试连结,连结时用trycatch捕捉数据库连结异常。
如果发生异常,就提示用户数据连结出错。
(2)订阅信息统计模块:
该模块将显示所有订阅信息,包括每个用户订了哪些报刊,报刊的份数,起至刊号及所订报刊的单价等所有数据信息,如图:
以下给出加载这些信息的函数。
_RecordsetPtrpRecord;
try
{
//生成Recordset实例
pRecord.CreateInstance("ADODB.Recordset");
//打开记录集,静态光标(静态记录集),乐观锁定方式
//查询所有语句
sql="selecto,customer.name,customer.addr,cus_order.orderdate,NMTABLE.title,NMTABLE.price,NMTABLE.period,cus_order.start,cus_order.term,cus_order.qtyfromcustomer,cus_order,[NMTABLE]whereo=cus_oandNMTABLE.nmno=cus_order.nmno";
pRecord->Open(_bstr_t(sql),_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
while(!
pRecord->adoEOF)
{
value=pRecord->GetCollect("cno");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.InsertItem(i,temp);
value=pRecord->GetCollect("name");
if(value.vt!
=VT_NULL)
temp=value.bstrVal;
else
temp="name";
m_list.SetItemText(i,1,temp.Trim());
value=pRecord->GetCollect("addr");
if(value.vt!
=VT_NULL)
temp=value.bstrVal;
else
temp="";
m_list.SetItemText(i,2,temp.Trim());
value=pRecord->GetCollect("orderdate");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.SetItemText(i,3,temp.Trim());
value=pRecord->GetCollect("title");
if(value.vt!
=VT_NULL)
temp=value.bstrVal;
else
temp="";
m_list.SetItemText(i,4,temp.Trim());
value=pRecord->GetCollect("period");
if(value.vt!
=VT_NULL)
temp=value.bstrVal;
else
temp="";
m_list.SetItemText(i,5,temp.Trim());
value=pRecord->GetCollect("start");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.SetItemText(i,6,temp);
value=pRecord->GetCollect("term");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.SetItemText(i,7,temp);
value=pRecord->GetCollect("qty");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.SetItemText(i,8,temp);
value=pRecord->GetCollect("price");
if(value.vt!
=VT_NULL)
{
value.ChangeType(VT_BSTR);
temp=value.bstrVal;
}
else
temp="";
m_list.SetItemText(i,9,temp);
i++;
pRecord->MoveNext();
}
pRecord->Close();
pRecord=NULL;
}
catch(_com_error*e)
{
MessageBox(e->ErrorMessage());
}
}
首先,如同创建Connection实例,这里先创建一个Recordset实例,它相当于一个查询结果的元组指针;然后构造SQL语句,实现三表联合查询;再通过Recordset的Open方法执行SQL语句,使用Recordset保存查询的结果。
最后,通过一个while循环,把Recordset中保存的结果全部读出,再将结果显示到列表框中,其中m_list是一个列表框的控制变量,先插入一行m_list.InsertItem(i,temp),i为列表框中现有的总项数,这样就可保证每次插入的数据是列表框的最后一项,由于已已经插入了一项,以后的就只要修改新插入项的数据即可m_list.SetItemText(i,9,temp)。
(3)删除统计信息中的某一项:
在列表框的某一项上右击,将显示一个菜单,如图:
添加对应的消息处理函数,当选中删除菜单时,将删除列表框中被选中数据项。
处理函数核心代码如下:
CStringSQL;
_CommandPtrm_pCommand;
inti;
i=m_list.GetSelectionMark();
SQL=(CString)"deletefrom[CUS_ORDER]whereCNO="+m_list.GetItemText(i,0);
SQL+="andNMNO=(selectNMNOfrom[NMTABLE]wheretitle='"+m_list.GetItemText(i,4)+"')";
//MessageBox(SQL);
try
{
m_pCommand.CreateInstance("ADODB.Command");
m_pCommand->ActiveConnection=theApp.m_pConnection;
m_pCommand->CommandText=_bstr_t(SQL);
m_pCommand->Execute(NULL,NULL,adCmdText);
//m_pCommand->Release();
}
catch(...)
{
MessageBox("执行SQL语句出错!
");
}
首先用m_list.GetSelectionMark()得到当前被选中的列表项,然后生成SQL语句,完成后,创建Command实例,再设置它的各项参数,最后执行。
(4)用户及报刊数据管理:
由于报刊数据和用户数据的管理类似,所以这里只对用户数据管理加以说明。
用户数据管理包括用户添加,用户信息修改,用户删除。
如图:
以下分别对这三个功能模块加之分析说明。
●数据添加:
输入姓名和地址后选择添加,程序就会将此用户作为一个新用户增加到数据库中。
添加按钮的消息处理函数如下:
CStringSQL,temp;
_CommandPtrm_pCommand;
GetDlgItem(IDC_EDIT3)->GetWindowText(temp);//cno,name,addrfrom[CUSTOMER]
SQL=(CString)"insertinto[CUSTOMER](name,addr)values('"+temp;
GetDlgItem(IDC_EDIT2)->GetWindowText(temp);
SQL+="','"+temp+"')";
try
{
m_pCommand.CreateInstance("ADODB.Command");
m_pCommand->ActiveConnection=theApp.m_pConnection;
m_pCommand->CommandText=_bstr_t(SQL);
m_pCommand->Execute(NULL,NULL,adCmdText);
//m_pCommand->Release();
}
catch(...)
{
MessageBox("执行SQL语句出错!
");
}
this->LoadUserData();
由于此函数和上面的右键菜单处理函数颇为相似,所以这里不加说明,后面的删除功能同理也不再叙述。
●数据更新操作:
当选择列表框中的任意一项时,处理列表框的LVN_ITEMCHANGED消息,使下面的文本框中数据也自动更新。
函数如下:
voidCFORMVIEW1:
:
OnLvnItemchangedList1(NMHDR*pNMHDR,LRESULT*pResult)
{
LPNMHEADERphdr=reinterpret_cast
//TODO:
在此添加控件通知处理程序代码
inti;
CStringtemp;
for(i=0;i { if(m_list0.GetItemState(i,LVIS_SELECTED)==LVIS_SELECTED)//选中状态。 。 { break; } } temp=m_list0.GetItemText(i,1); GetDlgItem(IDC_EDIT3)->SetWindowText(temp); temp=m_list0.GetItemText(i,2); GetDlgItem(IDC_EDIT2)->SetWindowText(temp); *pResult=0; } 首先用一个循环得到被选中的数据项的编号,然后再根据编号得到被选中项的用户姓名和地址。 再用SetWindowText函数更新下面的文本框的数据。 当单击更新按钮时,完成数据的更新操作。 先得到选中的数据项编号,再构造UPDATE语句,完成更新,由于更新操作也是使用Command实例,所以这里也不再复述。 (5)用户订报模块: 这是程序中最复杂的模块,它的功能是给指定的用户按要求订阅报刊,如图: 第一个列表框中显示的是系统中所有已登记的用户,左下方的列表中显示的是在用户列表框中选中的用户未订阅的报刊,右下方的列表中显示的就是此用户已订阅的报刊。 为便于理解程序,先给出它的操作方法: 假如要给用户“李宇”进行订报设置,就只要先在用户列表框中选中他,然后再在左下方的列表框中选择他要订阅的报刊(支持多选),填写好份数和起至刊号,最后只要单击“>>>>>”按钮即可完成订阅;同样假如他要取消订阅某刊物,就只要在右边的列表框中选中要取消的刊物名称,再单击“<<<<<”即可完成。 以下分块来讲解各功能的程序实现。 (a)由于选中用户列表框中某一用户,就要在下面的列表框中显示此用户未订的报刊和此用户用户已订的报刊。 这就要对用户列表框的LVN_ITEMCHANGED消息进行响应。 首先定义一个LoadNMData函数,它有一个参数用户ID,用来为下面的列表框加载数据。 函数代码如下: voidCFORMVIEW2: : LoadNMData(ints) { _RecordsetPtrpRecord; _variant_tvalue; CStringtemp,sql; inti=0; //清空list m_list1.DeleteAllItems(); m_list2.DeleteAllItems(); try { //生成Recordset实例 pRecord.CreateInstance("ADODB.Recordset"); //打开记录集,静态光标(静态记录集),乐观锁定方式 //查询所有语句未选报刊 sql=(CString)"selectnmno,title,period,pricefrom[NMTABLE]WHERENMNONOTIN(SELECTNMNOFROM[CUS_ORDER]WHERECNO=0"+m_list0.GetItemText(s,0)+(CString)")ORDERBYNMNO"; pRecord->Open(_bstr_t(sql),_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); while(! pRecord->adoEOF) { value=pRecord->GetCollect("nmno"); if(value.vt! =VT_NULL) { value.ChangeType(VT_BSTR); temp=value.bstrVal; } else temp=""; m_list1.InsertItem(i,temp); …… i++; pRecord->MoveNext(); } pRecord->Close(); //查询所有语句已选报刊 sql=(CString)"SELECTtitle,period,price,qty,start,termfrom[NMTABLE],[CUS_ORDER]WHERENMTABLE.NMNO=CUS_ORDER.NMNOANDCNO=0"+m_list0.GetItemText(s,0)+"ORDERBYNMTABLE.NMNO"; pRecord->Open(_bstr_t(sql),_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText); i=0; while(! pRecord->adoEOF) { value=pRecord->GetCollect("title"); if(value.vt! =VT_NULL) temp=value.bstrVal; else temp=""; m_list2.InsertItem(i,temp.Trim()); …… i++; pRecord->MoveNext(); } pRecord->Close(); pRecord=NULL; //GetDlgItem(IDC_EDIT1)->SetWindowText(m_list2.GetItemText(s,3)); } catch(...) { MessageBox("载入数据出错! "); } } 先创建Recordset实例,再构造SQL语句,执行,限于篇幅关系,这里不再复述。 再说LVN_ITEMCHANGED消息处理函数,它先得到选中的用户列表项,再据次得到用户ID,再调用LoadNMData函数,完成报刊列表的更新。 (b)用户订报功能的程序实现: 当单击“>>>>>”按钮时先在CUS_ORDER表中添加相应的用户订阅信息,调用LoadNMData对两列表数据进行更新。 函数代码如下: voidCFORMVIEW2: : OnBnClickedButton1() { CStringSQL,temp; inti,j,k; CStringqty,start,term; _CommandPtrm_pCommand; for(k=m_list0.GetItemCount()-1;k>=0;k--) { if(m_list0.GetItemState(k,LVIS_SELECTED)==LVIS_SELECTED) break; } j=m_list1.GetItemCount(); if(k<0||j==0||m_list1.GetSelectedCount()==0) { MessageBox("请先选择你要订阅的报刊! "); return; } GetDlgItem(IDC_EDIT1)->GetWindowText(qty); GetDlgItem(IDC_EDIT2)->GetWindowText(start); GetDlgItem(IDC_EDIT3)->GetWindowText(term); try { m_pCommand.CreateInstance("ADODB.Command"); m_pCommand->ActiveConnection=theApp.m_pConnection; for(i=0;i { if(m_list1.GetItemState(i,LVIS_SELECTED)==LVIS_SELECTED) { SQL=(CString)"INSERTINTO[CUS_ORDER](CNO,ORDERDATE,[NMNO],START,TERM,QTY)VALUES(0"+m_list0.GetItemText(k,0)+(CString)",GetDate()," +m_list1.GetItemText(i,0)+","+start+","+term+","+qty+")"; m_pCommand->CommandText=_bstr_t(SQL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 报刊 订阅 系统
![提示](https://static.bingdoc.com/images/bang_tan.gif)