4,017
社区成员
发帖
与我相关
我的任务
分享
//OnInitDialog中的连接代码
CString strSQL;
HRESULT hr;
try
{
hr=m_pConnection.CreateInstance(__uuidof(Connection));
strSQL="Provider=SQLOLEDB;Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=MyTest;Data Source=YOS-0222140854";
if(SUCCEEDED(hr))
{
hr=m_pConnection->Open(_bstr_t(strSQL),"","",adModeUnknown);
}
}
catch(_com_error e) //捕捉异常
{
CString errormessage;
errormessage.Format(_T("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage()));
AfxMessageBox(errormessage);//显示错误信息
return;
}
AfxMessageBox("连接成功");UINT CTestThreadDlg::Thread1(LPVOID lpParam)
{
CTestThreadDlg *pCurDlg = (CTestThreadDlg *)lpParam;
while (WaitForSingleObject(pCurDlg->m_hEvent,0)!=WAIT_OBJECT_0)
{
try
{
CString strSql = "insert into Table_1 values('000000000',1)";
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
_ConnectionPtr pConnection = pCurDlg->m_pConnection;
pConnection->Execute(_bstr_t(strSql),vtOptional,-1);
pCurDlg->m_iCount1++;
OutputDebugString("线程一操作成功\n");
}
catch(_com_error* e)
{
CString errormessage;
errormessage.Format("***********************线程一数据库使用失败:%s\n", e->ErrorMessage());
OutputDebugString(errormessage);
}
}
return 0;
}
UINT CTestThreadDlg::Thread2(LPVOID lpParam)
{
CTestThreadDlg *pCurDlg = (CTestThreadDlg *)lpParam;
while (WaitForSingleObject(pCurDlg->m_hEvent,0)!=WAIT_OBJECT_0)
{
try
{
CString strSql = "insert into Table_1 values('1111111111',2)";
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
_ConnectionPtr pConnection = pCurDlg->m_pConnection;
pConnection->Execute(_bstr_t(strSql),vtOptional,-1);
pCurDlg->m_iCount2++;
OutputDebugString("线程二操作成功\n");
}
catch (_com_error* e)
{
CString errormessage;
errormessage.Format("***********************线程二数据库使用失败:%s\n", e->ErrorMessage());
OutputDebugString(errormessage);
}
}
return 0;
}
UINT CTestThreadDlg::Thread3(LPVOID lpParam)
{
CTestThreadDlg *pCurDlg = (CTestThreadDlg *)lpParam;
while (WaitForSingleObject(pCurDlg->m_hEvent,0)!=WAIT_OBJECT_0)
{
try
{
CString strSql = "insert into Table_1 values('2222222222',3)";
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
_ConnectionPtr pConnection = pCurDlg->m_pConnection;
pConnection->Execute(_bstr_t(strSql),vtOptional,-1);
pCurDlg->m_iCount3++;
OutputDebugString("线程三操作成功\n");
}
catch (_com_error* e)
{
CString errormessage;
errormessage.Format("***********************线程三数据库使用失败:%s\n", e->ErrorMessage());
OutputDebugString(errormessage);
}
}
return 0;
}
UINT CTestThreadDlg::Thread4(LPVOID lpParam)
{
CTestThreadDlg *pCurDlg = (CTestThreadDlg *)lpParam;
while (WaitForSingleObject(pCurDlg->m_hEvent,0)!=WAIT_OBJECT_0)
{
try
{
_CommandPtr pCommandPtr;
pCommandPtr.CreateInstance("ADODB.Command");
_ConnectionPtr pConnectionPtr = pCurDlg->m_pConnection;
pCommandPtr->ActiveConnection = pConnectionPtr;
pCommandPtr->CommandText = "select * from Table_1";
_RecordsetPtr pRecordsetPtr = pCommandPtr->Execute(NULL,NULL,adCmdText);
_variant_t vName = pRecordsetPtr->GetCollect((_variant_t)(long)0);//取得第一个字段
CString sName = (LPCTSTR)_bstr_t(vName);
pCommandPtr.Release();
CString sText;
sText.Format("查询结果:%s",sName);
OutputDebugString(sText);
OutputDebugString("\n");
pCurDlg->m_iCount4++;
OutputDebugString("线程四操作成功\n");
}
catch (_com_error* e)
{
CString errormessage;
errormessage.Format("***********************线程四数据库使用失败:%s\n", e->ErrorMessage());
OutputDebugString(errormessage);
}
}
return 0;
}
UINT CTestThreadDlg::Thread5(LPVOID lpParam)
{
CTestThreadDlg *pCurDlg = (CTestThreadDlg *)lpParam;
while (WaitForSingleObject(pCurDlg->m_hEvent,0)!=WAIT_OBJECT_0)
{
try
{
CString strSql = "update Table_1 set age=100 where name='0000000000'";
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
_ConnectionPtr pConnection = pCurDlg->m_pConnection;
pConnection->Execute(_bstr_t(strSql),vtOptional,-1);
pCurDlg->m_iCount5++;
OutputDebugString("线程五操作成功\n");
}
catch (_com_error* e)
{
CString errormessage;
errormessage.Format("***********************线程五数据库使用失败:%s\n", e->ErrorMessage());
OutputDebugString(errormessage);
}
}
return 0;
}
void CTestThreadDlg::OnButton1()
{
// TODO: Add your control notification handler code here
OnButton1();
ResetEvent(m_hEvent);
m_iCount1=m_iCount2=m_iCount3=m_iCount4=m_iCount5=0;
AfxBeginThread((AFX_THREADPROC)Thread1, reinterpret_cast<LPVOID>(this));
AfxBeginThread((AFX_THREADPROC)Thread2, reinterpret_cast<LPVOID>(this));
AfxBeginThread((AFX_THREADPROC)Thread3, reinterpret_cast<LPVOID>(this));
AfxBeginThread((AFX_THREADPROC)Thread4, reinterpret_cast<LPVOID>(this));
AfxBeginThread((AFX_THREADPROC)Thread5, reinterpret_cast<LPVOID>(this));
}void CTestThreadDlg::OnButton3()
{
// TODO: Add your control notification handler code here
SetEvent(m_hEvent);
CString sText;
sText.Format("线程一插入%d\r\n线程二插入%d\r\n线程三插入%d\r\n线程四查询%d\r\n线程五更新%d",m_iCount1,m_iCount2,m_iCount3,m_iCount4,m_iCount5);
AfxMessageBox(sText);
m_pConnection->Release();
m_pConnection.Release();
}
可是我想问一个线程对应一个连接确实可以解决上述问题,如果连接多的话怎么办,假如一千个以上该怎么办?

问题越来越多了,真的很难理解:
SQL Server 2005 在访问数据库引擎的应用程序中引入了对多个活动结果集 (MARS) 的支持。 在 SQL Server 的早期版本中,数据库应用程序无法在单个连接上保持多个活动语句。 使用 SQL Server 默认结果集时,应用程序必须先处理或取消从某一批处理生成的所有结果集,然后才能对该连接执行任何其他批处理。 SQL Server 2005 引入了新的连接属性,该属性允许应用程序在每个连接上使用多个待定请求,具体而言,每个连接可以具有多个活动的默认结果集。
上面的红色字体说了,一个连接在同一时间只能有一个活动请求,可是我的这个小例子为什么可以啊,我用的就是SQL2000啊,在这个小例子中用的连接方式是ADO基于OLEDB直接连接,可是假如我换成ADO基于ODBC连接或者ADO基于OLEDB(OLEDB又基于ODBC)连接的话就会很快崩溃并且报如下错误:[Microsoft][ODBC SQL Server Driver]连接占线导致另一个 hstmt,按照上面的那段话这个报错应该是正常的,因为SQL2000不支持MARS,可是换种连接方式(就是我例子中用的连接方式)为什么就可以???
我知道在开发中最好一个线程一个连接,我只是想知道出错的原因!!