VC++6.0通过MFC 创建了 对话框 ,然后怎样通过SQL Server 连接到数据库?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++6.0通过MFC 创建了 对话框 ,然后怎样通过SQL Server 连接到数据库?相关的知识,希望对你有一定的参考价值。

我用VC++创建了几个关联的对话框,然后我想连接到SQL Server数据库,该怎么办?我已经创建了一个数据库Library ,数据源也已经配置好了。

class DBConnection

public:
DBConnection(void);
~DBConnection(void);
int OpenConnect(void);
int ExecuteSQL(_bstr_t strCmd);
_RecordsetPtr GetRecondSetPrt();
private:
_ConnectionPtr m_pConnection; //链接数据库德指针变量
_RecordsetPtr m_pRecordset; //指向记录集的指针
_variant_t RecordsAffected; //受影响的记录条数
;

DBConnection::DBConnection(void)

m_pConnection=NULL;
m_pRecordset=NULL;


DBConnection::~DBConnection(void)

m_pConnection=NULL;
m_pRecordset=NULL;


//打开数据库链接
int DBConnection::OpenConnect(void)

try

//创建连接对象
m_pConnection.CreateInstance("ADODB.Connection");

//设置连接字符串

_bstr_t strConnect ="Provider=SQLOLEDB;Data Source=20110121-1545\\SQLEXPRESS;\
Initial Catalog=ExpManDB;User ID=sa;PWD=123";

//设置连接超时时间为5秒
m_pConnection->ConnectionTimeout = 5;

//连接数据库
m_pConnection->Open(strConnect, "", "", adModeUnknown);
return 1;


catch(_com_error e)

CString errorMsg;
errorMsg.Format(_T("连接数据库失败!\r错误信息:%s"),(LPCSTR)e.ErrorMessage());
AfxMessageBox(errorMsg);
return 0;



//返回受影响的记录条数
int DBConnection::ExecuteSQL(_bstr_t strCmd)

if(m_pConnection->State)

try

m_pRecordset.CreateInstance("ADODB.Recordset"); //为Recordset对象创建实例
//执行SQL语句,并返回受影响的记录条数
m_pRecordset=m_pConnection->Execute(strCmd,&RecordsAffected,adCmdText);
return RecordsAffected.intVal;

catch(_com_error &e)

AfxMessageBox(e.Description());
return 0;


return 0;


//返回记录集以便后续使用
_RecordsetPtr DBConnection::GetRecondSetPrt()

return m_pRecordset;

可以像这样使用,strCmd为sql语句
DBConnection dbConnector;
if(dbConnector.OpenConnect() == 0)

return;

if(dbConnector.ExecuteSQL((_bstr_t)strCmd) == 0)

return;

当然如果你还需要取出数据的时候可以这样用
_RecordsetPtr pRecordSet;
pRecordSet=dbConnector.GetRecondSetPrt();
_variant_t vCardNo;
vCardNo = pRecordSet->GetCollect("cardNO"); //得到数据表种cardNO字段
后面_variant_t类型就可以转换为int float CString等各种类型了。
如果有什么问题再交流。
参考技术A 你可以创建一个数据连接的公共类:DataBase
这样就很方便在其它类来使用它了。
DataBase::DataBase()



DataBase::~DataBase()



void DataBase::ConnectDB()//创建连接

::CoInitialize(NULL);
try
m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
_bstr_t str = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Library ;";//Library是你的数据库名
this->m_pConnection->Open(str, "sa", "sa", adModeUnknown);
catch(_com_error e)
AfxMessageBox("connect error!");



bool DataBase::ExecuteQuery(CString sql)//执行查询

_bstr_t bSql = sql;
try
this->m_pRecordset = m_pConnection->Execute(bSql,NULL,adCmdText);
catch(_com_error e)
//AfxMessageBox("Recordset error!");
return false;

return true;


bool DataBase::Close()

return (!FAILED(m_pRecordset->Close()));

在其它类调用时:DataBase db;
db.ConnectDB();
CString sql = "select * from xxTable";
db.ExecuteQuery(sql);
db.Close();
参考技术B LINUX / ODBC / mysql

#ifdef WIN32
#include <windows.h>
#include <odbcinst.h>
#include <sqlext.h>
#else
#include <mysql.h>
#include <unistd.h>
#define SQLHANDLE static MYSQL
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

SQLHANDLE hDBEnv, hDBC;

int DB_Open(char * dbcn, char * usr, char * pwd)

int r;
#ifdef WIN32
r = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hDBEnv);
if(r) return 0;
r = SQLSetEnvAttr(hDBEnv,SQL_ATTR_ODBC_VERSION,
(void*)SQL_OV_ODBC3,0);
if(r) return 0;
r = SQLAllocHandle(SQL_HANDLE_DBC, hDBEnv, &hDBC);
if(r) return 0;
r = SQLConnect(hDBC,
(unsigned char *)dbcn, strlen(dbcn),
(unsigned char *)usr, strlen(usr),
(unsigned char *)pwd, strlen(pwd));
return r==SQL_SUCCESS || r==SQL_SUCCESS_WITH_INFO;
#else
mysql_init(&hDBC);
MYSQL * rx = mysql_real_connect(
&hDBC, dbcn, usr, pwd, NULL, 0, NULL, 0);
if(!rx) return 0;
return 1;
#endif
//end DB_Open

int DB_Exec(char * sql)

#ifdef WIN32
SQLHANDLE hStatement = NULL;
SQLAllocHandle(SQL_HANDLE_STMT, hDBC, &hStatement);
SQLExecDirect(hStatement,(unsigned char *)sql, strlen(sql));
SQLCloseCursor(hStatement);
SQLFreeHandle(SQL_HANDLE_STMT, hStatement);
hStatement = NULL;
#else
mysql_real_query (&hDBC, sql, strlen(sql));
#endif
return 1;
//end DB_Exec

int DB_Close(void)

#ifdef WIN32
SQLDisconnect(hDBC);
SQLFreeHandle(SQL_HANDLE_DBC, hDBC);
SQLFreeHandle(SQL_HANDLE_ENV, hDBEnv);
#else
mysql_close(&hDBC);
#endif
return 1;
//DB_Close()

#ifndef WIN32
typedef struct tagMySQLRecordset
MYSQL_RES * hRecord;
void * * row;
int * size;
int cols;
MYSQLRecordset;

#endif

void DB_CleanQuery(void *hRecordset)

if(!hRecordset) return;
#ifdef WIN32
__try
SQLCloseCursor(hRecordset);
SQLFreeHandle(SQL_HANDLE_STMT, hRecordset);
hRecordset = NULL;
__finally
return;
//end try
#else
MYSQLRecordset * hRec = (MYSQLRecordset *) hRecordset;
mysql_free_result (hRec->hRecord);
free(hRec->row); hRec->row = NULL;
free(hRec->size); hRec->size = NULL;
free(hRec); hRec = NULL;
#endif
//end DB_CleanQuery

int DB_Next(void * hRecordset)

int r=0; if(!hRecordset) return 0;
#ifdef WIN32
r = SQLFetch(hRecordset);
r = r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO;
if(!r)
DB_CleanQuery(hRecordset);
//end if
#else
MYSQLRecordset * hRec = (MYSQLRecordset *) hRecordset;
MYSQL_ROW row = mysql_fetch_row (hRec->hRecord);
if(row)
for(int i=0; i<hRec->cols; i++)
memcpy(hRec->row[i], row[i], hRec->size[i]);
//next i
r = 1;
else
DB_CleanQuery(hRecordset);
r = 0;
//end if
#endif
return r;
//end DB_Next

int DB_params_count(const char * fmt)

int i=0, j=0;
while(fmt[i])
if(fmt[i]=='%') j++;
i++;
//end while
return j;
//end DB_params_count

void * DB_Query(char *sql, const char *fmt, ...)

int r=0;
int cols = DB_params_count(fmt);
if(cols<1) return NULL;
#ifdef WIN32
SQLHANDLE hStatement = NULL;
SQLAllocHandle(SQL_HANDLE_STMT, hDBC, &hStatement);
r = SQLExecDirect(hStatement,(unsigned char *)sql, strlen(sql));
r = r==SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO;
if(!r)
return NULL;
//end if
#else
r = mysql_real_query (&hDBC, sql, strlen(sql));
if(r) return NULL;
MYSQL_RES * rec = NULL;
rec = mysql_store_result (&hDBC);
if(!rec) return NULL;
MYSQLRecordset * hStatement
= (MYSQLRecordset *)malloc(sizeof(MYSQLRecordset));
if(!hStatement) return NULL;
memset(hStatement, 0, sizeof(MYSQLRecordset));
hStatement->hRecord = rec;
hStatement->cols = cols;
hStatement->row = (void **)malloc(cols * sizeof(void *));
memset(hStatement->row, 0, cols * sizeof(void *));
hStatement->size = (int *)malloc(cols * sizeof(int));
memset(hStatement->size, 0, cols * sizeof(int));
#endif
va_list ap; va_start(ap, fmt);
void * var; char buf[32];
int i=0,j=0,k=0,sz=0; char c=0;
int len = strlen(fmt); int bad=1;
#ifdef WIN32
int col=1;
#else
int col=0;
#endif
while(fmt[i])
c = fmt[i++];
if(c != '%') continue;
c = fmt[i++];
var = va_arg(ap, void *);
if(c == 'd')
#ifdef WIN32
SQLBindCol(hStatement, col, SQL_C_SLONG, var, 4,NULL);
#else
hStatement->row[col] = var;
hStatement->size[col] = sizeof(long);
#endif
col++;
continue;
//end if
if(c == 'f')
#ifdef WIN32
SQLBindCol(hStatement, col, SQL_C_FLOAT, var, 4,NULL);
#else
hStatement->row[col] = var;
hStatement->size[col] = sizeof(float);
#endif
col++;
continue;
//end if
memset(buf, 0, 32); bad=1;
for(j=i-1; j<len; j++)
c = fmt[j];
if(c>='0' && c<='9') buf[j-i+1]=c;
if(c=='s')
//next j
if(bad) return NULL;
sscanf(buf, "%d", &sz);
#ifdef WIN32
SQLBindCol(hStatement, col, SQL_C_CHAR, var, sz, NULL);
#else
hStatement->row[col] = var;
hStatement->size[col] = sz;
#endif
col++;
i = k;
//end while
va_end(ap);
return hStatement;
//end DB_Rec

创建线程会在终止时挂起 MFC 对话框应用程序

【中文标题】创建线程会在终止时挂起 MFC 对话框应用程序【英文标题】:Creating a thread hangs MFC dialog app on termination 【发布时间】:2010-07-19 03:51:27 【问题描述】:

我已经缩小了一个问题的范围。

    我创建了一个简单的对话框应用程序 VC++ 6.0。 我在主线程之前启动了一个线程 对话框 DoModal() 被调用 我退出应用程序 - 有时 应用程序立即关闭, 其他时候它会挂起 10 秒 左右

这是什么原因造成的?我试过 _beginthread()、_beginthreadex() 和 AfxBeginThread()。他们都做同样的事情。

如果我在 DoModal() 调用之后添加 Sleep(50)(当 GUI 完成处理时),程序似乎每次都会毫无问题地终止。

使我缩小这个问题的原因是我有一个 Win32 DLL 可以做同样的事情。我的 DLL 有一个线程,我注意到使用这个 DLL 的应用程序有时需要一段时间才能停止。消除 DLL 并创建最简单的程序会产生相同的结果 - 这就是我上面所描述的。

以下是我添加到沼泽标准 MFC 对话框应用程序中的代码:

UINT Thread( void * )

  for( ;; )
  
    Sleep( 50 );
  

  AfxEndThread( 0 );
  return 0;


/////////////////////////////////////////////////////////////////////////////
// CThreadTest2App initialization

BOOL CThreadTest2App::InitInstance()

    AfxEnableControlContainer();

    // Standard initialization
    // If you are not using these features and wish to reduce the size
    //  of your final executable, you should remove from the following
    //  the specific initialization routines you do not need.

#ifdef _AFXDLL
    Enable3dControls();         // Call this when using MFC in a shared DLL
#else
    Enable3dControlsStatic();   // Call this when linking to MFC statically
#endif

  AfxBeginThread( Thread, 0 );

    CThreadTest2Dlg dlg;
    m_pMainWnd = &dlg;
    int nResponse = dlg.DoModal();

  //Sleep( 50 );   // Works when I add this ?????

    if (nResponse == IDOK)
    
    
    else if (nResponse == IDCANCEL)
    
    

    // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application's message pump.
    return FALSE;

有人可以帮我正确关闭我的应用程序吗?我最终想要做的是提供一种让我的 DLL 关闭的方法,而无需通过调用应用程序明确告知它停止 thead。

谢谢 保罗

【问题讨论】:

【参考方案1】:

好吧,你的线程函数中有无限循环,永远不会调用AfxEndThread

如果你想从外部停止线程,你必须在其中编写一个信号机制,如果你必须停止,检查循环内部。

【讨论】:

好的 - 那么为什么会有所不同呢?您在线程内添加一个标志测试并在对话框完成后设置标志 - 您将遇到同样的问题。可能需要执行 3-4 次才能明白我的意思,但请试一试。 但目前你的线程被操作系统杀死,而不是你自己。这可能会因需要的时间而异。

以上是关于VC++6.0通过MFC 创建了 对话框 ,然后怎样通过SQL Server 连接到数据库?的主要内容,如果未能解决你的问题,请参考以下文章

MFC如何调用DLL(VC++)

VC 6.0 MFC关闭对话框在win7出现崩溃的情况

vc6.0 mfc窗口问题

VC6 如何调用MFC类

openCV在VC6.0中的配置问题

VC++(MFC)中动态创建和管理按钮控件,怎么做?