在C++中连接数据库

longay00 2009-05-25 01:27:09
最近我遇到了以个棘手的问题,就是如何在C++中去连接Access数据库,前提是没有数据源,没有引擎,没有数据库,要使用语句创建数据库
...全文
634 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
longay00 2009-06-23
  • 打赏
  • 举报
回复

对不起,你们到现在为止,没有人能够解决我的难题。但是我已经说过,这个问题已经有了一个解决办法,现在公布如下,我希望你们有人能够想出更好的办法。
问题重述:做一个没有引擎,没有数据库文件的数据库程序。功能:在程序中自己创建数据库文件,注意:没有引擎,没有多余的数据库文件。
我知道这个问题很难,用C++做数据库本身就不容易。原代码如下:
#import "c:\Program Files\Common Files\System\ADO\Msadox.dll" rename_namespace("ADOCG") rename("EOF", "adoXEOF") rename("DataTypeEnum","adoXDataTypeEnum")


#import "C:\Program Files\Common Files\System\ADO\msado15.dll" named_guids rename("EOF","adoEOF"), rename("BOF","adoBOF")

using namespace ADODB;
using namespace ADOCG;

#define TESTHR(x) if FAILED(x) _com_issue_error(x);


//2.创建ACCESS数据库

BOOL CDeRenDlg::CreateMdb(CString strDBName)
{
CString strMdbConn = "Provider='Microsoft.JET.OLEDB.4.0';Data source = " + strDBName;

try
{
HRESULT hr = S_OK;
_CatalogPtr pCatalog = NULL;
_bstr_t cnnstring(strMdbConn);

TESTHR(hr = pCatalog.CreateInstance(__uuidof (Catalog)));
pCatalog->Create(cnnstring);
}

catch(_com_error e)
{
_bstr_t bstrDescription(e.Description());
CString strErro=CString(_T("创建ACCEESS数据库出错: "))
+ (LPCSTR)e.Description()
+ CString(_T("Create ACCESS DB error: "))
+ (LPCSTR)e.Description();
AfxMessageBox(strErro);
return FALSE;
}

return TRUE;
}


//3.创建数据库表-材料表
BOOL CDeRenDlg::CreateTable( CString strTabName)
{
HRESULT hr = S_OK;

_CatalogPtr pCatalog = NULL;
_TablePtr pTableNew = NULL;
_IndexPtr pIndexNew = NULL;
_IndexPtr pIndex = NULL;
_ColumnPtr pColumn = NULL;

CString strConn,strDBName;

strDBName=this->GetDBName(m_nDBYear);
CFileFind ff;
if(!ff.FindFile(strDBName))
{
AfxMessageBox("数据库不存在,请先在高级设置对话框中创建数据库!");
return FALSE;
}

strConn="Provider='Microsoft.JET.OLEDB.4.0';Data source = " + strDBName;

_bstr_t strcnn(strConn);
try
{
TESTHR(hr = pCatalog.CreateInstance (__uuidof(Catalog)));
TESTHR(hr = pTableNew.CreateInstance(__uuidof(Table)));
TESTHR(hr = pIndexNew.CreateInstance(__uuidof(Index)));
TESTHR(hr = pIndex.CreateInstance (__uuidof(Index)));
TESTHR(hr = pColumn.CreateInstance (__uuidof(Column)));

// 连接
pCatalog->PutActiveConnection(strcnn);

// 表名
pTableNew->Name = _bstr_t(strTabName);
pTableNew->ParentCatalog = pCatalog;


//
//m_pTableNew->Columns->Append("ContactId", ::adInteger,0);
//m_pTableNew->Columns->GetItem("ContactId")->Properties->GetItem("AutoIncrement")->Value = true;


// 加入字段
CString str;
str = _T("公司名称");//"公司名称";
pTableNew->Columns->Append(_variant_t(str), ADOCG::adVarWChar, 50);
pTableNew->Columns->GetItem(_variant_t(str))->Properties->GetItem("Jet OLEDB:Allow Zero Length")->Value =false; //将必填字段设置为否

str = _T("产品名称");//"产品名称";
pTableNew->Columns->Append(_variant_t(str), ADOCG::adVarWChar, 50);
pTableNew->Columns->GetItem(_variant_t(str))->Properties->GetItem("Jet OLEDB:Allow Zero Length")->Value =false;

str = _T("产品规格");//"产品名称";
pTableNew->Columns->Append(_variant_t(str), ADOCG::adVarWChar, 50);
pTableNew->Columns->GetItem(_variant_t(str))->Properties->GetItem("Jet OLEDB:Allow Zero Length")->Value =false;

//*
// 加入主键
pIndexNew->Name = "pryIndex";//"日期";
pIndexNew->Columns->Append(_variant_t(str), ADOCG::adVarWChar, 50);

pIndexNew->PutPrimaryKey(-1);
pIndexNew->PutUnique(-1);
pTableNew->Indexes->Append(_variant_t ((IDispatch*)pIndexNew));
//*/

// 加入表中
pCatalog->Tables->Append(_variant_t ((IDispatch*)pTableNew));
pCatalog->Tables->Refresh();

}
catch(_com_error &e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
AfxMessageBox(e.Description());
return FALSE;

}

return TRUE;
}

//4.判断一个表在数据库中是否存在

BOOL CDeRenDlg::IsTalbeExit(CString strTable)
{
try
{
if(!m_adoConnection.IsOpen()) return FALSE;

_RecordsetPtr pRstSchema = NULL;

pRstSchema=m_adoConnection.OpenSchema(adSchemaTables);

while(!pRstSchema->adoEOF)
{
_bstr_t table_name = pRstSchema->Fields->GetItem("TABLE_NAME")->Value;
_bstr_t table_type = pRstSchema->Fields->GetItem("TABLE_TYPE")->Value;
if ( strcmp(((LPCSTR)table_type),"TABLE")==0)
{
if(strTable.Compare((LPCSTR)table_name)==0)return true;
}

pRstSchema->MoveNext();
}

if(pRstSchema) pRstSchema->Close(); /*&&(pRstSchema->State==ADODB::adStateOpen)*/
}
catch(_com_error e)//
{
::MessageBox(NULL,e.Description(),"Error",MB_OK);
return FALSE;
}

return false;

}
Dinelgua 2009-06-02
  • 打赏
  • 举报
回复
把创建数据库脚本写好,用c++调 呵呵
HeroAlur 2009-06-02
  • 打赏
  • 举报
回复
用MySql 有API的

如果是小型软件
推荐使用嵌入式数据库SQLite
longay00 2009-06-02
  • 打赏
  • 举报
回复
到目前为止没有人能够解决这个问题,上面的问题描述没有错,另外说明,我们没有额外的数据库文件,还有这个问题已经有了一个解决的办法,这里我只想要一个更好的,难到这里没有人了吗?
字云逸 2009-05-25
  • 打赏
  • 举报
回复
呵呵,学习
  • 打赏
  • 举报
回复
//没有引擎行吗??

//连接ACCESS 指定文件地址就OK我用的是test.mdb
//pConn->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb;Persist Security Info=False;Jet OLEDB:Database Password=";
  • 打赏
  • 举报
回复
我这里有一个代码
只要一个MDB文件就OK了的

void CMy01Dlg::OnSqlConnect()
{
// TODO: Add your control notification handler code here
//初始化COM对象
CoInitialize(NULL);
_ConnectionPtr pConn(__uuidof(Connection));//连接对象
_RecordsetPtr pRst(__uuidof(Recordset));//记录集对象
_CommandPtr pCmd(__uuidof(Command));//COMMAND对象
//设置连接字符串
/*在VC中 连接SQl Server数据的字符串:Driver={SQL Server};Server=.;Database=test;Trusted_Connection=Yes;
说明MySqlServer为数据库服务器名或Ip地址,MyTable为数据库表4};
在VC中连接Access数据的字符串Astr.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=..\\SHMS.mdb;Persist Security Info=False;Jet OLEDB:Database Password=287803603");
*/
//连接ACCESS 指定文件地址就OK我用的是test.mdb
//pConn->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb;Persist Security Info=False;Jet OLEDB:Database Password=";

//连接SQL SERVER
pConn->ConnectionString="Driver={SQL Server};Server=.;Database=mystudent;Trusted_Connection=Yes;";


//////////////////////////////////////////////////////////////ss
pConn->Open("","","",adConnectUnspecified);
//连接对象查询 记录获取数据
//方法1
//pRst=pConn->Execute("select * from student",NULL,adCmdText);

//方法2
pRst->Open("select C_NAME FROM TB_MSG",_variant_t((IDispatch*)pConn),adOpenDynamic,adLockOptimistic,adCmdText);
//方法三:
//pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConn));
//pCmd->CommandText="select * from student";
//pRst=pCmd->Execute(NULL,NULL,adCmdText);

//显示数据

while(!pRst->rsEOF)
{
MessageBox((_bstr_t)pRst->GetCollect("C_NAME"));
pRst->MoveNext();
}
//关闭记录集、连接
pConn->Execute("update TB_MSG set C_NAME='……' where C_ID=1",NULL,adCmdText);
pRst->Close();
pConn->Close();
//释放资源
pCmd.Release();
pRst.Release();
pConn.Release();
CoUninitialize();

}


MMMoonriver 2009-05-25
  • 打赏
  • 举报
回复
wanghao111 2009-05-25
  • 打赏
  • 举报
回复
ado
Sou2012 2009-05-25
  • 打赏
  • 举报
回复
UP..
pathuang68 2009-05-25
  • 打赏
  • 举报
回复
Access2007以前的版本:
楼主可以分析一下MDB数据库的格式,并不复杂,在UltraEdit下面看看 + 网上搜搜。
zbihong 2009-05-25
  • 打赏
  • 举报
回复
研究精神可嘉!!!帮顶!!!
98440622 2009-05-25
  • 打赏
  • 举报
回复
干吗对自己这么狠呢,呵呵~~

不知道用COM能不能直接访问Access文件,如果可以的话,试试看能不能通过“读"文件的方法操作access吧,至于SQL支持嘛,大概要自己写解释器了吧。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧