酒店点餐系统开发详解(四)

酒店点餐系统开发详解(四),第1张

概述酒店点餐系统开发详解(四) ——数据库模块设计   在本系统中每个模块与数据库的一系列查询、插入、删除等 *** 作是通过类CDatabaseOperation进行的,所有的数据库 *** 作都封装在这个类中。数据库功能的封装增加了模块的独立性和复用性,便于进行二次开发和软件的修改。 本系统采用ADO对象进行数据库 *** 作,故应在stdafx.h中添加“#import "c:/program files/common

酒店点餐系统开发详解(四)

——数据库模块设计

 

在本系统中每个模块与数据库的一系列查询、插入、删除等 *** 作是通过类cdatabaSEOperation进行的,所有的数据库 *** 作都封装在这个类中。数据库功能的封装增加了模块的独立性和复用性,便于进行二次开发和软件的修改。

本系统采用ADO对象进行数据库 *** 作,故应在stdafx.h中添加“#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","_EOF")”(不包括引号),每个模块刚启动并连接数据库的 *** 作如下:

BOol CCookTerminalApp::InitInstance()

{

……

AfxEnableControlContainer();

::CoInitialize(NulL);//初始化com环境

//网络连接初始化

AfxSocketinit(NulL);

//数据库连接

ConnectsqlServer();

……

}

//连接数据库

voID CCookTerminalApp::ConnectsqlServer()

{

CString IP,User,Passwd;

int Port;

GetPrivateProfileString("sqlServer","IP","local",IP.GetBuffer(20),20,".//default.ini");

IP.ReleaseBuffer();

GetPrivateProfileString("sqlServer","User","sa",User.GetBuffer(20),".//default.ini");

User.ReleaseBuffer();

GetPrivateProfileString("sqlServer","Passwd","",Passwd.GetBuffer(20),".//default.ini");

Passwd.ReleaseBuffer();

Port = GetPrivateProfileInt("sqlServer","Port",1433,".//default.ini");

//数据库连接初始化

m_DbOp.CreateInstance();

if(IP == "local")

m_DbOp.OpenLocalDatabase("dishesSystem");

else{

CString str;

str.Format("%s,%d",IP,Port);

m_DbOp.OpenRemoteDatabase(str,"dishesSystem",Passwd);

}

}

cdatabaSEOperation的具体接口及实现如下:

1、创建实例

voID cdatabaSEOperation::CreateInstance()

{

cnn.CreateInstance(__uuIDof(Connection));

rst.CreateInstance(__uuIDof(Recordset));

}

2、打开本地数据库

voID cdatabaSEOperation::OpenLocalDatabase(CString basename)

{

CString str;

str.Format(_T("ProvIDer=sqlolEDB.1;Data Source=(local);Initial Catalog=%s;Integrated Security=sspI"),basename);

cnn->ConnectionString = (_bstr_t)str;

try{

cnn->Open(L"",L"",adCmdUnspecifIEd);

}catch(_com_error &e){

CatchError(e);

}

}

3、打开远程数据库

voID cdatabaSEOperation::OpenRemoteDatabase(CString source, CString basename, CString user, CString pwd)

{

CString str;

str.Format(_T("ProvIDer=sqlolEDB.1;Data Source=%s;Network library=DBMSSOCN;Initial Catalog=%s;User ID=%s;Password=%s"),source,basename,user,pwd);

cnn->ConnectionString = (_bstr_t)str;

try{

cnn->Open(L"",adCmdUnspecifIEd);

}catch(_com_error &e){

CatchError(e);

}

}

4、打开记录集

BOol cdatabaSEOperation::OpenRecordset(CString sqlstatement)

{

CloseRecordset();

try{

rst->CursorLocation = adUseClIEnt;

rst->Open((_variant_t)sqlstatement,_variant_t((Idispatch *)cnn,true),adOpenDynamic,adLock@R_888_3270@,adCmdText);

}catch(_com_error &e){

// CatchError(e);

return FALSE;

}

return TRUE;

}

5、关闭记录集

voID cdatabaSEOperation::CloseRecordset()

{

if(rst->State)

rst->Close();

}

6、返回记录集

_RecordsetPtr cdatabaSEOperation::GetRecordset(CString sqlstatement)

{

_RecordsetPtr rst;

rst.CreateInstance(__uuIDof(Recordset));

try{

rst->CursorLocation = adUseClIEnt;

rst->Open((_variant_t)sqlstatement,adCmdText);

}catch(_com_error &e){

// CatchError(e);

return NulL;

}

return rst;

}

7、插入新数据

BOol cdatabaSEOperation::InsertItem(CString sqlstatement)

{

try{

cnn->Execute((_bstr_t)sqlstatement,NulL,adCmdText);

}catch(_com_error &e){

CatchError(e);

return FALSE;

}

return TRUE;

}

8、修改数据

BOol cdatabaSEOperation::UpdateItem(CString sqlstatement)

{

try{

cnn->Execute((_bstr_t)sqlstatement,adCmdText);

}catch(_com_error &e){

CatchError(e);

return FALSE;

}

return TRUE;

}

9、删除数据

BOol cdatabaSEOperation::DeleteItem(CString sqlstatement)

{

try{

cnn->Execute((_bstr_t)sqlstatement,adCmdText);

}catch(_com_error &e){

CatchError(e);

return FALSE;

}

return TRUE;

}

10、返回属性值

CString cdatabaSEOperation::GetAttrValues(CString attr)

{

_variant_t vt;

CString values;

if(rst->_EOF || rst->BOF)

return "";

try{

vt = rst->GetCollect((_variant_t)attr);

}catch(_com_error &e){

CatchError(e);

return "";

}

values = (LPCSTR)_bstr_t(vt);

return values;

}

11、读取数据库图片数据

char *cdatabaSEOperation::ReadPictureData(CString sqlstatement, CString attrname)

{

_RecordsetPtr temp_rst;

char *buf = NulL;

temp_rst.CreateInstance(__uuIDof(Recordset));

try{

temp_rst->Open((_variant_t)sqlstatement,adCmdText);

}catch(_com_error &e){

CatchError(e);

return NulL;

}

long lDataSize;

try{

lDataSize = temp_rst->GetFIElds()->GetItem((_variant_t)attrname)->ActualSize;

}catch(_com_error &e){

CatchError(e);

return NulL;

}

if(lDataSize > 0)

{

_variant_t varBLOB;

try{

varBLOB = temp_rst->GetFIElds()->GetItem((_variant_t)attrname)->GetChunk(lDataSize);

}catch(_com_error &e){

CatchError(e);

return NulL;

}

if(varBLOB.vt == (VT_ARRAY | VT_UI1))

{

if(buf = new char[lDataSize+1]) ///重新分配必要的存储空间

{

char *pBuf = NulL;

SafeArrayAccessData(varBLOB.parray,(voID **)&pBuf);

memcpy(buf,pBuf,lDataSize); ///复制数据到缓冲区

SafeArrayUnaccessData (varBLOB.parray);

}

}

}

return buf;

}

12、保存图片到数据库

BOol cdatabaSEOperation::SavePicture(CString sqlstatement, CString attrname, char *buf, long len)

{

if(buf == NulL)

return TRUE;

char *pBuf = buf;

VARIANT varBLOB;

SAFEARRAY *psa;

    SAFEARRAYBOUND rgsabound[1];

_RecordsetPtr temp_rst;

temp_rst.CreateInstance(__uuIDof(Recordset));

try{

temp_rst->Open((_variant_t)sqlstatement,adCmdText);

}catch(_com_error &e){

CatchError(e);

return FALSE;

}

if(temp_rst->_EOF)

return FALSE;

if(pBuf)

{    

rgsabound[0].lLbound = 0;

rgsabound[0].cElements = len;

psa = SafeArrayCreate(VT_UI1, 1, rgsabound);

for (long i = 0; i < (long)len; i++)

SafeArrayPutElement (psa, &i, pBuf++);

varBLOB.vt = VT_ARRAY | VT_UI1;

varBLOB.parray = psa;

temp_rst->GetFIElds()->GetItem((_variant_t)attrname)->AppendChunk(varBLOB);

}

temp_rst->Update();

temp_rst->Close();

return TRUE;

}

在实际的 *** 作中,我们将常用的数据库 *** 作整理为存储过程编译到数据库中,以下就是本系统所涉及的具体存储过程:

从厨师表中删除厨师(DeleteCook @cookID 

1)本过程先查看点菜表中是否存在相关记录,若存在,则不允许删除厨师,因为顾客还没结账;若不存在,则先删除做菜表中记录,再删除厨师表中记录。

--删除厨师,需先将Cookingtabledishedtable中的相关项删除

CREATE PROCEDURE DeleteCook @cookID char(8)

AS

--如果点菜表中含有相关项,说明顾客未结账,则不允许删除

IF EXISTS (SELECT * FROM dishedtable WHERE cookID=@cookID)

     RETURN

ELSE 

IF EXISTS (SELECT * FROM Cookingtable WHERE cookID=@cookID)

     DELETE FROM Cookingtable WHERE cookID=@cookID

DELETE FROM Cooktable WHERE cookID=@cookID

2)从菜品表中删除菜品(Deletedish @dishID

本过程同样先检查点菜表中是否有相关项,若有,则不允许删除菜品;若无,则先删除做菜表中记录,再删除菜品表中记录。

--删除菜品信息,先检查dishedtableCookingtable中有无相关项

CREATE PROCEDURE Deletedish @dishID char(8)

AS

--如果点菜表中含有相关项,说明顾客未结账,则不允许删除

IF EXISTS (SELECT * FROM dishedtable WHERE dishID=@dishID)

      RETURN

ELSE 

IF EXISTS (SELECT * FROM Cookingtable WHERE dishID=@dishID)

      DELETE FROM Cookingtable WHERE dishID=@dishID

DELETE FROM dishestable WHERE dishID=@dishID

3)销售统计(Salesstatistics @date,@sales

本过程首先检查表中是否存在日期相同的记录,若存在,则将原记录中的销售额加上新数据;若不存在,则直接插入新数据。

--销售统计函数

CREATE PROCEDURE Salesstatistics @date char(10),@sales float

AS

--如果表中存在该项,则增加销售额

IF EXISTS (SELECT * FROM Salesstatisticstable WHERE date=@date)

    UPDATE Salesstatisticstable SET sales=sales+@sales WHERE date=@date

ELSE

--否则,插入新数据

    INSERT INTO Salesstatisticstable (date,sales) VALUES(@date,@sales)

4)搜索拿手菜表(SearchSpecialty @cookname

cookname'%%',则显示所有表中数据,否则,显示某一厨师的拿手菜信息。所返回结果先按厨师名排序,然后再按喜爱度排序。

--搜索拿手菜表

CREATE PROCEDURE SearchSpecialty @cookname nchar(50)

AS

IF @cookname='%%'

   SELECT DT.dishID as 菜品编号,left(dishname,LEN(dishname)) as 菜品名称,

           CT.cookID as 厨师编号,left(cookname,LEN(cookname)) as 厨师姓名,

           average as 喜爱度,dishprice as 菜品单价

   FROM Specialtytable ST INNER JOIN dishestable DT ON ST.dishID=DT.dishID

         INNER JOIN Cooktable CT ON ST.cookID=CT.cookID

         ORDER BY cookname ASC,average DESC  --先按厨师名排序,再按平均分排序

ELSE

   SELECT DT.dishID as 菜品编号,dishprice as 菜品单价

   FROM Specialtytable ST INNER JOIN dishestable DT ON ST.dishID=DT.dishID

         INNER JOIN Cooktable CT ON ST.cookID=CT.cookID

   WHERE cookname liKE @cookname

         ORDER BY cookname ASC,average DESC   --先按厨师名排序,再按平均分排序

5)点菜(dishedFuction @dishedtime ,@deskID @dishID ,@cookID

本过程先查看表中是否存在相同记录,若存在,则将所点菜品份数amount1,菜品总价cost自动加上相应菜品单价;若不存在,则直接插入新数据。

--点菜 *** 作

CREATE PROCEDURE dishedFuction 

       @dishedtime char(19),@deskID int,@dishID char(8),@cookID char(8)

AS

DECLARE @price float

SELECT @price=dishprice FROM dishestable WHERE dishID=@dishID

IF EXISTS (SELECT * FROM dishedtable WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID)

     UPDATE dishedtable SET amount=amount+1,cost=cost+@price

        WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID

ELSE

     INSERT INTO dishedtable (dishedtime,deskID,dishID,cookID,cost,amount) 

                  VALUES(@dishedtime,@deskID,@dishID,@cookID,@price,1)

6)退菜(ReturndishFuction @dishedtime,@dishID

本过程先查看菜品份数amount是否为1,若为1,则直接删除该记录;若不为1,则将菜品份数amount1,然后菜品总价cost减去相应菜品单价。

--退菜 *** 作

CREATE PROCEDURE ReturndishFuction 

       @dishedtime char(19),@dishID char(8)

AS    DECLARE @price float

SELECT @price=dishprice FROM dishestable WHERE dishID=@dishID

--如果点菜表中存在该项则将点菜份数-1,菜品总价递减

IF EXISTS (SELECT * FROM dishedtable WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID)

BEGIN  DECLARE @amount int

        SELECT @amount=amount FROM dishedtable WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID

IF @amount=1

   DELETE FROM dishedtable WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID

ELSE   

        UPDATE dishedtable SET amount=amount-1,cost=cost-@price

        WHERE dishedtime=@dishedtime AND deskID=@deskID AND dishID=@dishID

END

7)评分(scoreFuction @cookID,@dishID ,@score

本过程先检查表中是否存在相同记录,若存在,则将评分次数freq1,总分scores加上此次分数,并计算平均分;若不存在,则插入新数据。

--对厨师所做菜品进行评分

CREATE PROCEDURE scoreFuction @cookID char(8),@score int

AS

--如果表中存在该项,则将评次加1,总分增加,并求出平均分

IF EXISTS (SELECT * FROM Cookingtable WHERE cookID=@cookID AND dishID=@dishID)

   BEGIN

      DECLARE @f int,@s int,@a int

      SELECT @f=freq,@s=scores FROM Cookingtable WHERE cookID=@cookID AND dishID=@dishID

      SET @f=@f+1

      SET @s=@s+@score

      SET @a=@s/@f

      UPDATE Cookingtable SET freq=@f,scores=@s,average=@a

              WHERE cookID=@cookID AND dishID=@dishID

   END

ELSE

   INSERT INTO Cookingtable (cookID,freq,scores,average) 

                VALUES(@cookID,1,@score,@score)

 

8)搜索点菜表(Searchdished @dishedtime ,@deskID

本过程用于向顾客返回其所点菜品信息,并对厨师所做菜品进行评分。

--搜索点菜表

CREATE PROCEDURE Searchdished @dishedtime char(19),@deskID int

AS

SELECT DdT.dishID as 菜品编号,

DdT.cookID as 厨师编号,

amount as 点菜份数,cost as 菜品总价

FROM dishedtable DdT INNER JOIN dishestable DsT ON DdT.dishID=DsT.dishID

              INNER JOIN Cooktable CkT ON DdT.cookID=CkT.cookID

WHERE dishedtime=@dishedtime AND deskID=@deskID

9)获取账单信息(GetAccountInfo @dishedtime,@deskID

本过程用于结账时显示顾客所点菜品的详细信息。

--获取账单详细信息

CREATE PROCEDURE GetAccountInfo @dishedtime char(19),cost as 总价

FROM dishedtable DdT INNER JOIN dishestable DsT ON DdT.dishID=DsT.dishID

       INNER JOIN Cooktable CkT ON DdT.cookID=CkT.cookID

WHERE dishedtime=@dishedtime AND deskID=@deskID

10)搜索菜品表(Searchdishes @dishname

本过程显示搜索菜品表的结果。

--搜索菜品表

CREATE PROCEDURE Searchdishes @dishname nchar(50)

AS

IF @dishname='%%%%'

SELECT dishID as 菜品编号,dishprice as 菜品单价

    FROM dishestable

ELSE

SELECT dishID as 菜品编号,dishprice as 菜品单价

   FROM dishestable WHERE dishname liKE @dishname

源代码下载地址:http://download.csdn.net/source/2406335 标题有误,请见谅...

总结

以上是内存溢出为你收集整理的酒店点餐系统开发详解(四)全部内容,希望文章能够帮你解决酒店点餐系统开发详解(四)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1183194.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存