我的程序用的是VC+ADO访问Oracle数据库,程序运行一段时间就会报出ORA-01000: 超出打开游标的最大数错误。我在数据库中查看了当前打开的游标,我的程序打开的游标都关闭了,不知道问题出在哪里,请指教
下面附上出问题的代码段
BOOL #######::*******(CString PartCode,CString FaultCode,int FaultNO,CString FilePath,int ImgNO)
{
CFile infile;
CString Postion[4],strFindTime;
CString strTrainSerial,strVehicleSerial;
BOOL bRet = FALSE; //检查数据库连接是否正常
if (!g_DB_Recong.CheckDBConn())
{
WriteTFDSLog("数据库连接断开,重新连接数据库!");
bRet = g_DB_Recong.ReConnect(g_pDlg->m_sService,g_pDlg->m_sUserID,g_pDlg->m_sUserPwd);
if (!bRet)
{
WriteTFDSLog("重连数据库失败!");
return FALSE;
}
} if(g_Gmc)
{
strTrainSerial = g_pDlg->m_RecongData[0].TrainSerial;
strVehicleSerial = g_pDlg->m_RecongData[0].VehicleSerial;
}
else
{
strTrainSerial = g_pDlg->m_OtherRecongData[0].TrainSerial;
strVehicleSerial = g_pDlg->m_OtherRecongData[0].VehicleSerial;
} Postion[0].Format("%d",m_FaultRect.left);
Postion[1].Format("%d",m_FaultRect.right);
Postion[2].Format("%d",m_FaultRect.top);
Postion[3].Format("%d",m_FaultRect.bottom); try
{
infile.Open(FilePath,CFile::modeRead|CFile::typeBinary);
}
catch (_com_error err)
{
g_DB_Recong.write_com_error("打开文件失败!",err);
return FALSE;
}
long nSize = infile.GetLength(); CTime time = CTime::GetCurrentTime();
strFindTime = time.Format("%Y-%m-%d %H:%M:%S"); CString strSql;
CADORecordset* pRs = new CADORecordset(g_DB_Recong.m_pDB);
if(pRs == NULL)
{
WriteTFDSLog("创建记录集失败!");
return FALSE;
} try
{
strSql.Format("insert into tf_******_auto(TRAIN_SERIAL,VEHICLE_SERIAL,FAULT_NUMBER,FAULT_PLACE,FAULT_ID, \
DETECTOR, DETECT_TIME, FOUND_MODE,PONDERANCE, POSITION_LEFT, POSITION_RIGHT, POSITION_TOP,POSITION_BOTTOM,IMG_LENGTH,IMG_INDEX) \
values('%s','%s','%d','%s','%s','%s',to_date('%s','yyyy-mm-dd hh24:mi:ss'),'%s','%s','%s','%s','%s','%s','%d','%d')",
strTrainSerial,
strVehicleSerial,
FaultNO,
PartCode,
FaultCode,
"计算机",
strFindTime,
"1",
"0",
Postion[0],
Postion[1],
Postion[2],
Postion[3],
nSize,
ImgNO);
WriteTFDSLog("打开记录集");
if (!pRs->Open((LPCTSTR)strSql))
{
// 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集");
}
delete pRs;
pRs = NULL;
WriteTFDSLog("故障信息写数据库失败!"); return FALSE;
}
else
{
WriteTFDSLog("故障信息写数据库成功!");
}
// 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集");
}
}
catch (_com_error err)
{
CString strMsg;
strMsg = _T("插入故障信息出错");
g_DB_Recong.write_com_error(strMsg,err);
if (pRs != NULL)
{
pRs->Close();
delete pRs;
pRs = NULL;
}
return FALSE;
} try
{
WriteTFDSLog("故障图片入库");
CString strFaultNO;
strFaultNO.Format("%d",FaultNO);
strSql = "select IMG_DATA from tf_******_auto \
where TRAIN_SERIAL = '" + strTrainSerial
+ "' and VEHICLE_SERIAL = '" + strVehicleSerial + "' and FAULT_NUMBER =" + strFaultNO;
if (pRs->Open((LPCTSTR)strSql))
{
WriteTFDSLog("打开记录集");
//按文件的大小在堆上申请内存块
BYTE * pBuffer = new BYTE [nSize];
//把jpg文件读到pBuffer
if (infile.Read(pBuffer, nSize) > 0 )
{
BOOL bRet;
bRet = pRs->AppendChunk("IMG_DATA",pBuffer,nSize);
if (!bRet)
WriteTFDSLog("AppendChunk() 执行失败"); bRet = pRs->Update();
if(!bRet)
WriteTFDSLog("Update() 执行失败"); infile.Close();
WriteTFDSLog("读图像文件数据入缓存成功");
}
else
{
WriteTFDSLog("读图像文件数据入缓存失败");
return FALSE;
}
//删掉堆上申请的内存
delete [] pBuffer;
pBuffer = NULL;
WriteTFDSLog("释放内存成功"); // 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close(); //出问题都是在执行这句的时候进入异常之后执行close还是失败
WriteTFDSLog("关闭记录集0");
}
WriteTFDSLog("关闭记录集成功");
}
else
{
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集00");
}
delete pRs;
pRs = NULL;
return FALSE;
}
}
catch (_com_error err)
{
CString strMsg;
strMsg = _T("插入故障信息出错");
g_DB_Recong.write_com_error(strMsg,err);
// 关闭记录集,释放空间
if (pRs != NULL)
{
pRs->Close();
delete pRs;
pRs = NULL;
}
return FALSE;
}
delete pRs;
pRs = NULL; return TRUE;
}
请高手帮忙,问题解决在奉上100分。
下面附上出问题的代码段
BOOL #######::*******(CString PartCode,CString FaultCode,int FaultNO,CString FilePath,int ImgNO)
{
CFile infile;
CString Postion[4],strFindTime;
CString strTrainSerial,strVehicleSerial;
BOOL bRet = FALSE; //检查数据库连接是否正常
if (!g_DB_Recong.CheckDBConn())
{
WriteTFDSLog("数据库连接断开,重新连接数据库!");
bRet = g_DB_Recong.ReConnect(g_pDlg->m_sService,g_pDlg->m_sUserID,g_pDlg->m_sUserPwd);
if (!bRet)
{
WriteTFDSLog("重连数据库失败!");
return FALSE;
}
} if(g_Gmc)
{
strTrainSerial = g_pDlg->m_RecongData[0].TrainSerial;
strVehicleSerial = g_pDlg->m_RecongData[0].VehicleSerial;
}
else
{
strTrainSerial = g_pDlg->m_OtherRecongData[0].TrainSerial;
strVehicleSerial = g_pDlg->m_OtherRecongData[0].VehicleSerial;
} Postion[0].Format("%d",m_FaultRect.left);
Postion[1].Format("%d",m_FaultRect.right);
Postion[2].Format("%d",m_FaultRect.top);
Postion[3].Format("%d",m_FaultRect.bottom); try
{
infile.Open(FilePath,CFile::modeRead|CFile::typeBinary);
}
catch (_com_error err)
{
g_DB_Recong.write_com_error("打开文件失败!",err);
return FALSE;
}
long nSize = infile.GetLength(); CTime time = CTime::GetCurrentTime();
strFindTime = time.Format("%Y-%m-%d %H:%M:%S"); CString strSql;
CADORecordset* pRs = new CADORecordset(g_DB_Recong.m_pDB);
if(pRs == NULL)
{
WriteTFDSLog("创建记录集失败!");
return FALSE;
} try
{
strSql.Format("insert into tf_******_auto(TRAIN_SERIAL,VEHICLE_SERIAL,FAULT_NUMBER,FAULT_PLACE,FAULT_ID, \
DETECTOR, DETECT_TIME, FOUND_MODE,PONDERANCE, POSITION_LEFT, POSITION_RIGHT, POSITION_TOP,POSITION_BOTTOM,IMG_LENGTH,IMG_INDEX) \
values('%s','%s','%d','%s','%s','%s',to_date('%s','yyyy-mm-dd hh24:mi:ss'),'%s','%s','%s','%s','%s','%s','%d','%d')",
strTrainSerial,
strVehicleSerial,
FaultNO,
PartCode,
FaultCode,
"计算机",
strFindTime,
"1",
"0",
Postion[0],
Postion[1],
Postion[2],
Postion[3],
nSize,
ImgNO);
WriteTFDSLog("打开记录集");
if (!pRs->Open((LPCTSTR)strSql))
{
// 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集");
}
delete pRs;
pRs = NULL;
WriteTFDSLog("故障信息写数据库失败!"); return FALSE;
}
else
{
WriteTFDSLog("故障信息写数据库成功!");
}
// 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集");
}
}
catch (_com_error err)
{
CString strMsg;
strMsg = _T("插入故障信息出错");
g_DB_Recong.write_com_error(strMsg,err);
if (pRs != NULL)
{
pRs->Close();
delete pRs;
pRs = NULL;
}
return FALSE;
} try
{
WriteTFDSLog("故障图片入库");
CString strFaultNO;
strFaultNO.Format("%d",FaultNO);
strSql = "select IMG_DATA from tf_******_auto \
where TRAIN_SERIAL = '" + strTrainSerial
+ "' and VEHICLE_SERIAL = '" + strVehicleSerial + "' and FAULT_NUMBER =" + strFaultNO;
if (pRs->Open((LPCTSTR)strSql))
{
WriteTFDSLog("打开记录集");
//按文件的大小在堆上申请内存块
BYTE * pBuffer = new BYTE [nSize];
//把jpg文件读到pBuffer
if (infile.Read(pBuffer, nSize) > 0 )
{
BOOL bRet;
bRet = pRs->AppendChunk("IMG_DATA",pBuffer,nSize);
if (!bRet)
WriteTFDSLog("AppendChunk() 执行失败"); bRet = pRs->Update();
if(!bRet)
WriteTFDSLog("Update() 执行失败"); infile.Close();
WriteTFDSLog("读图像文件数据入缓存成功");
}
else
{
WriteTFDSLog("读图像文件数据入缓存失败");
return FALSE;
}
//删掉堆上申请的内存
delete [] pBuffer;
pBuffer = NULL;
WriteTFDSLog("释放内存成功"); // 关闭记录集,释放空间
if(pRs != NULL)
{
pRs->Close(); //出问题都是在执行这句的时候进入异常之后执行close还是失败
WriteTFDSLog("关闭记录集0");
}
WriteTFDSLog("关闭记录集成功");
}
else
{
if(pRs != NULL)
{
pRs->Close();
WriteTFDSLog("关闭记录集00");
}
delete pRs;
pRs = NULL;
return FALSE;
}
}
catch (_com_error err)
{
CString strMsg;
strMsg = _T("插入故障信息出错");
g_DB_Recong.write_com_error(strMsg,err);
// 关闭记录集,释放空间
if (pRs != NULL)
{
pRs->Close();
delete pRs;
pRs = NULL;
}
return FALSE;
}
delete pRs;
pRs = NULL; return TRUE;
}
请高手帮忙,问题解决在奉上100分。
will open on your behalf, cursors the database must open to perform recursive SQL.For example, if you are in forms and have a default block and nothing else and run that
form, you'll find (before doing ANYTHING) you have some cursors open. Forms (your
application framework) has done some sql and cached the cursors on your behalf.As you do more work in forms (eg: query up a row, update a field in the row) you'll see
more and more cursors appear. Some you opened (by doing the query). Others were opened
on your behalf (eg: forms locking the record for us when we updated the field).You might also see some cursors come and go that reference SYS tables. These would be
recursive queries and would happen when the optimizer parses your query, needs to
allocate space for your query and so on.You might also see other cursor come into play when triggers fire, stored procedures run
and so on.
It is not possible for 2 sessions to share the same exact cursor but it is highly
probable that 2 sessions will share the same "shared_pool" entry for the underlying query
(see SHARED SQL in the concepts guide). A cursor is in your space, the parse tree,
optimization, security and such is in a shared space.It should be noted that OPEN_CURSORS simply allocates a fixed number of slots but does
not allocate memory for these slots for a client (eg: it sets an array up to have 1,000
cursors for example but does not allocate 1,000 cursors). Rather, we will allocate 64
cursor contexts at a time, as needed (so the first cursor will allocate 64 contexts, the
65'th will get 64 more and so on). So, setting open-cursors to 1,000 or so it not
harmful (but don't go overboard and set it to 1,000,000 or something ;) 我通常OPEN_CURSORS会设置为1500或者更大。
还有就是关闭游标的操作要放到finally里面。