求助:一个数据库访程序的各种问题

后浪如何浪 2016-03-20 09:24:06
编写的控制台应用程序,运行后总是出各种问题,有时候可以写入数据,有时候又会失败,关闭记录集指针也总是出问题。求大牛帮忙调试下程序,并指导下,我对数据库也不是很了解。主要帮忙调试下程序,指出错误在哪就好。
#include <icrsint.h>
#include<iostream>
#include "stdafx.h"
#include "string.h"
using namespace std;
class CADO
{public:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
public :
void Connect(void);
void ExitConnect(void);
_RecordsetPtr&GetRecordset(_bstr_t SQL);
};
/* 建立数据库连接*/
void CADO::Connect(void)
{
try{::CoInitialize(NULL);//初始化com环境
m_pConnection.CreateInstance(__uuidof(Connection));//创建连接对象
m_pConnection->Open("Provider=Microsoft Office 12.0 Access Database Engine OLE DB Provider;Data Source=F:\\VC_work\\Northwind.mdb","","",adModeUnknown);
}
catch(_com_error e)
{
cout<<"连接数据库失败!错误信息:"<<e.ErrorMessage()<<endl;
return;
}
cout<<"连接成功!"<<endl;
}
void CADO:: ExitConnect(void)
{
if(!m_pRecordset->adoEOF)
{//m_pRecordset.Release();
m_pRecordset->Close();
m_pConnection->Close();

}
::CoUninitialize();//释放环境

}
/*得到记录集*/
_RecordsetPtr& CADO ::GetRecordset(_bstr_t SQL)
{_variant_t ra;
try{if (m_pConnection==NULL)
Connect();
m_pRecordset.CreateInstance(__uuidof(Recordset));
// 取得表中的记录
m_pRecordset->Open(SQL,/*_variant_t((IDispatch*)m_pConnection,true)*/m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
// 捕捉异常
catch(_com_error e)
{
// 显示错误信息
printf("错误信息:%s",e.Description());
cout<<"错误信息:"<<e.ErrorMessage()<<endl;

}
return m_pRecordset;

}
class stu:public CADO
{
private:
long ID;
string Name;
long Age;
public:
stu(){ID=0;Name="**";Age=0;}
stu(int id,string name,int age){ID=id;Name=name;Age=age;}
void writedata(_bstr_t SQLl);
};
void stu::writedata(_bstr_t SQLl)
{
Connect();
GetRecordset(SQLl);
while(!m_pRecordset->adoEOF)
m_pRecordset->MoveNext();
m_pRecordset->AddNew();///添加新记录
m_pRecordset->PutCollect("ID",_variant_t((long)(ID)));
m_pRecordset->PutCollect("Name",_variant_t("na"));
m_pRecordset->PutCollect("Age",_variant_t((long)(Age)));

}
void main()
{
stu s1(1,"dd",3);
s1.writedata("SELECT * FROM 表1");
s1.ExitConnect();
}
...全文
129 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiqiang01234 2016-03-22
  • 打赏
  • 举报
回复
无非是用c接口封装了一下ado,更通用一些
后浪如何浪 2016-03-22
  • 打赏
  • 举报
回复
引用 3 楼 jiqiang01234 的回复:

#ifndef _ADO_SQL_H_
#define _ADO_SQL_H_

#ifndef ADO_API
	#ifdef __cplusplus
		#define ADO_API extern "C" __declspec(dllimport)	
	#else
		#define ADO_API __declspec(dllimport)	
	#endif
#else
	#undef ADO_API
	#ifdef __cplusplus
		#define ADO_API extern "C" __declspec(dllexport)	
	#else
		#define ADO_API __declspec(dllexport)	
	#endif	
#endif

#ifndef STDCALL
#define STDCALL __stdcall 
#endif

#ifndef Bool
#define Bool int
#endif

#ifndef True
#define True 1
#endif

#ifndef False
#define False 0
#endif



struct ADOConn;

#define ADO_FIELD_NAME_LEN		64
#define ADO_FIELD_VALUE_LEN		(8 * 1024)
struct ADOFieldInfo
{
	char name[ADO_FIELD_NAME_LEN];
	char value[ADO_FIELD_VALUE_LEN];
};

typedef void (STDCALL* ADOQueryCallback)(const struct ADOFieldInfo* info, int fieldCount, void* user);

ADO_API Bool STDCALL ADO_Initialize(); 
ADO_API void STDCALL ADO_Uninitialize();


ADO_API struct ADOConn* STDCALL ADO_CreateConnection(const char* connString);
ADO_API void STDCALL ADO_DestroyConnection(struct ADOConn* conn);

ADO_API Bool STDCALL ADO_Exec(struct ADOConn* conn, const char* sql);
ADO_API void STDCALL ADO_Query(struct ADOConn* conn, const char* sql, ADOQueryCallback cb, void* user);

#endif

// ADOSql.cpp : ¶¨Òå DLL Ó¦ÓóÌÐòµÄµ¼³öº¯Êý¡£
//
#include "stdafx.h"

#define ADO_API
#include "ADOSql.h"

#import "c:\\program files\\common files\\system\\ado\\msado15.dll" no_namespace rename("EOF", "adoEOF")


struct ADOConn 
{
	_ConnectionPtr connPtr;
};

static void ADO_GetFieldValue(const _variant_t& var, char* value);

ADO_API Bool STDCALL ADO_Initialize()
{
	HRESULT r = CoInitialize(NULL);
	return r == S_OK || r == S_FALSE;
}

ADO_API void STDCALL ADO_Uninitialize()
{
	CoUninitialize();
}

ADO_API struct ADOConn* STDCALL ADO_CreateConnection(const char* connString)
{
	struct ADOConn* conn = NULL;
	try
	{
		conn = new struct ADOConn;
		if(FAILED(conn->connPtr.CreateInstance("ADODB.Connection")))
			throw false;

		if(FAILED(conn->connPtr->Open(connString, "", "", adConnectUnspecified)))
			throw false;
	}
	catch (...)
	{
		if(conn != NULL)
		{
			if(conn->connPtr != NULL && (conn->connPtr->GetState() & adStateOpen))
			{
				conn->connPtr->Close();
			}

			delete conn;
			conn = NULL;
		}
	}

	return conn;
}

ADO_API void STDCALL ADO_DestroyConnection(struct ADOConn* conn)
{
	try
	{
		conn->connPtr->Close();		
		conn->connPtr.Release();
		delete conn->connPtr;
	}
	catch(...)
	{
	}
}

ADO_API Bool STDCALL ADO_Exec(struct ADOConn* conn, const char* sql)
{
	try
	{
		return conn->connPtr->Execute(sql, NULL, adCmdText);
	}
	catch(...)
	{
		return False;
	}
}

ADO_API void STDCALL ADO_Query(struct ADOConn* conn, const char* sql, ADOQueryCallback cb, void* user)
{
	_RecordsetPtr rs;
	try
	{
		rs.CreateInstance("ADODB.Recordset");
		if (SUCCEEDED(rs->Open(sql, conn->connPtr.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText)))
		{
			long fieldCount = rs->GetFields()->GetCount();
			std::auto_ptr<struct ADOFieldInfo> ptr(new struct ADOFieldInfo[fieldCount]);
			rs->MoveFirst();
			while(!rs->adoEOF)
			{
				memset(ptr.get(), 0, sizeof(struct ADOFieldInfo) * fieldCount);
				for (long i = 0; i < fieldCount; i++)
				{
					struct ADOFieldInfo* info = ptr.get() + i;
					strncpy(info->name, rs->GetFields()->GetItem(i)->GetName(), ADO_FIELD_NAME_LEN);
					
					ADO_GetFieldValue(rs->GetCollect(i), info->value);
				}

				(*cb)(ptr.get(), fieldCount, user);

				rs->MoveNext();
			}

			rs->Close();
		}
	}
	catch(...)
	{
		if(rs != NULL && (rs->GetState() & adStateOpen))
		{
			rs->Close();
		}
	}
}

//////////////////////////////////////////////////////////////////////////
static void ADO_GetFieldValue(const _variant_t& var, char* value)
{
	switch(var.vt)
	{
	case VT_EMPTY:
	case VT_NULL:		
		break;
	case VT_DECIMAL:
		sprintf(value, "%I64d", (LONGLONG)var);
		break;
	case VT_I1:
		sprintf(value, "%c", (char)var);
		break;
	case VT_UI1:	
		sprintf(value, "%u", (BYTE)var);
		break;
	case VT_I2:
		sprintf(value, "%d", (SHORT)var);
		break;
	case VT_UI2:
		sprintf(value, "%u", (USHORT)var);
		break;
	case VT_I4:
		sprintf(value, "%d", (INT32)var);
		break;
	case VT_UI4:
		sprintf(value, "%u", (UINT32)var);
		break;
	case VT_I8:
		sprintf(value, "%I64d", (LONGLONG)var);
		break;
	case VT_UI8:
		sprintf(value, "%I64u", (ULONGLONG)var);
	case VT_R4:
		sprintf(value, "%f", (float)var);
		break;
	case VT_R8:
		sprintf(value, "%f", (double)var);
		break;
	case VT_BOOL:
		sprintf(value, "%d", (bool)var);
		break;
	case VT_DATE:
		{
			SYSTEMTIME st;
			VariantTimeToSystemTime(var, &st);
			sprintf(value, "%04d-%02d-%02d %02d:%02d:%02d.%03d", 
				st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
		}
		break;
	case VT_BSTR:
		strncpy(value, static_cast<const char*>((_bstr_t)var), ADO_FIELD_VALUE_LEN);
		break;
	default:
		assert(0);
		break;
	}

}
看不懂
后浪如何浪 2016-03-21
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
单步调试程序以检查问题所在
调试过,然而依旧不会改,应该是记录集指针不对
jiqiang01234 2016-03-21
  • 打赏
  • 举报
回复

#ifndef _ADO_SQL_H_
#define _ADO_SQL_H_

#ifndef ADO_API
	#ifdef __cplusplus
		#define ADO_API extern "C" __declspec(dllimport)	
	#else
		#define ADO_API __declspec(dllimport)	
	#endif
#else
	#undef ADO_API
	#ifdef __cplusplus
		#define ADO_API extern "C" __declspec(dllexport)	
	#else
		#define ADO_API __declspec(dllexport)	
	#endif	
#endif

#ifndef STDCALL
#define STDCALL __stdcall 
#endif

#ifndef Bool
#define Bool int
#endif

#ifndef True
#define True 1
#endif

#ifndef False
#define False 0
#endif



struct ADOConn;

#define ADO_FIELD_NAME_LEN		64
#define ADO_FIELD_VALUE_LEN		(8 * 1024)
struct ADOFieldInfo
{
	char name[ADO_FIELD_NAME_LEN];
	char value[ADO_FIELD_VALUE_LEN];
};

typedef void (STDCALL* ADOQueryCallback)(const struct ADOFieldInfo* info, int fieldCount, void* user);

ADO_API Bool STDCALL ADO_Initialize(); 
ADO_API void STDCALL ADO_Uninitialize();


ADO_API struct ADOConn* STDCALL ADO_CreateConnection(const char* connString);
ADO_API void STDCALL ADO_DestroyConnection(struct ADOConn* conn);

ADO_API Bool STDCALL ADO_Exec(struct ADOConn* conn, const char* sql);
ADO_API void STDCALL ADO_Query(struct ADOConn* conn, const char* sql, ADOQueryCallback cb, void* user);

#endif

// ADOSql.cpp : ¶¨Òå DLL Ó¦ÓóÌÐòµÄµ¼³öº¯Êý¡£
//
#include "stdafx.h"

#define ADO_API
#include "ADOSql.h"

#import "c:\\program files\\common files\\system\\ado\\msado15.dll" no_namespace rename("EOF", "adoEOF")


struct ADOConn 
{
	_ConnectionPtr connPtr;
};

static void ADO_GetFieldValue(const _variant_t& var, char* value);

ADO_API Bool STDCALL ADO_Initialize()
{
	HRESULT r = CoInitialize(NULL);
	return r == S_OK || r == S_FALSE;
}

ADO_API void STDCALL ADO_Uninitialize()
{
	CoUninitialize();
}

ADO_API struct ADOConn* STDCALL ADO_CreateConnection(const char* connString)
{
	struct ADOConn* conn = NULL;
	try
	{
		conn = new struct ADOConn;
		if(FAILED(conn->connPtr.CreateInstance("ADODB.Connection")))
			throw false;

		if(FAILED(conn->connPtr->Open(connString, "", "", adConnectUnspecified)))
			throw false;
	}
	catch (...)
	{
		if(conn != NULL)
		{
			if(conn->connPtr != NULL && (conn->connPtr->GetState() & adStateOpen))
			{
				conn->connPtr->Close();
			}

			delete conn;
			conn = NULL;
		}
	}

	return conn;
}

ADO_API void STDCALL ADO_DestroyConnection(struct ADOConn* conn)
{
	try
	{
		conn->connPtr->Close();		
		conn->connPtr.Release();
		delete conn->connPtr;
	}
	catch(...)
	{
	}
}

ADO_API Bool STDCALL ADO_Exec(struct ADOConn* conn, const char* sql)
{
	try
	{
		return conn->connPtr->Execute(sql, NULL, adCmdText);
	}
	catch(...)
	{
		return False;
	}
}

ADO_API void STDCALL ADO_Query(struct ADOConn* conn, const char* sql, ADOQueryCallback cb, void* user)
{
	_RecordsetPtr rs;
	try
	{
		rs.CreateInstance("ADODB.Recordset");
		if (SUCCEEDED(rs->Open(sql, conn->connPtr.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText)))
		{
			long fieldCount = rs->GetFields()->GetCount();
			std::auto_ptr<struct ADOFieldInfo> ptr(new struct ADOFieldInfo[fieldCount]);
			rs->MoveFirst();
			while(!rs->adoEOF)
			{
				memset(ptr.get(), 0, sizeof(struct ADOFieldInfo) * fieldCount);
				for (long i = 0; i < fieldCount; i++)
				{
					struct ADOFieldInfo* info = ptr.get() + i;
					strncpy(info->name, rs->GetFields()->GetItem(i)->GetName(), ADO_FIELD_NAME_LEN);
					
					ADO_GetFieldValue(rs->GetCollect(i), info->value);
				}

				(*cb)(ptr.get(), fieldCount, user);

				rs->MoveNext();
			}

			rs->Close();
		}
	}
	catch(...)
	{
		if(rs != NULL && (rs->GetState() & adStateOpen))
		{
			rs->Close();
		}
	}
}

//////////////////////////////////////////////////////////////////////////
static void ADO_GetFieldValue(const _variant_t& var, char* value)
{
	switch(var.vt)
	{
	case VT_EMPTY:
	case VT_NULL:		
		break;
	case VT_DECIMAL:
		sprintf(value, "%I64d", (LONGLONG)var);
		break;
	case VT_I1:
		sprintf(value, "%c", (char)var);
		break;
	case VT_UI1:	
		sprintf(value, "%u", (BYTE)var);
		break;
	case VT_I2:
		sprintf(value, "%d", (SHORT)var);
		break;
	case VT_UI2:
		sprintf(value, "%u", (USHORT)var);
		break;
	case VT_I4:
		sprintf(value, "%d", (INT32)var);
		break;
	case VT_UI4:
		sprintf(value, "%u", (UINT32)var);
		break;
	case VT_I8:
		sprintf(value, "%I64d", (LONGLONG)var);
		break;
	case VT_UI8:
		sprintf(value, "%I64u", (ULONGLONG)var);
	case VT_R4:
		sprintf(value, "%f", (float)var);
		break;
	case VT_R8:
		sprintf(value, "%f", (double)var);
		break;
	case VT_BOOL:
		sprintf(value, "%d", (bool)var);
		break;
	case VT_DATE:
		{
			SYSTEMTIME st;
			VariantTimeToSystemTime(var, &st);
			sprintf(value, "%04d-%02d-%02d %02d:%02d:%02d.%03d", 
				st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
		}
		break;
	case VT_BSTR:
		strncpy(value, static_cast<const char*>((_bstr_t)var), ADO_FIELD_VALUE_LEN);
		break;
	default:
		assert(0);
		break;
	}

}
paschen 版主 2016-03-20
  • 打赏
  • 举报
回复
单步调试程序以检查问题所在

64,691

社区成员

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

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