1、使用ADO对数据库进行数据插入操作,并且使用批更新方式。
AdoWriteConn.m_pRecordset->UpdateBatch(adAffectAll);//写入recordset记录集中的所有记录的挂起更改
2、代码每次运行到上面的这一行就报下面的错,但是我点继续,程序还能正常运行,数据也正常更新进了数据库:
Firstchance exception at 0x000007FEFD7BAAAD in BOTDR_QUICK_DB_v3.0.exe: Microsoft C++ exception: _com_error at memory location 0x000000000905F170。
3、报错时的状态如下:
4、分析问题可得:
首先数据库连接正常,记录集打开正常,数据插入记录集也正常,只有执行批更新的时候发发生了异常,说明是数据向数据库发送的时候出现问题,想到的可能原因有
(1)经网上资料查找,很多都在说ado的updatebatch()函数的问题,说明这可能是一个ado的bug;
(2)可能在执行updatebatch()的时候数据库连接异常;
(3)可能是数据库方面的问题;
5、添加try catch()异常捕获后,报错如下:
XXXXXXXXX-v1.0Dlg.cpp(2460) : atlTraceGeneral - Warning: 数据库写入线程WriteDatabaseThread发生异常. 错误信息: 未指定的错误; 文件:XXXXXXXXX-v1.0Dlg.cpp; 行: 2459
对于“未指定的错误”这个问题,还是一脸懵逼啊,网上找了半天找不到解决办法,最后求助了论坛,一位大佬说我的trycatch()异常捕获代码写的不全,无法获取完整的错误代码和错误描述,于是我修改了之后,重新调试运行,终于找到了原因:
atlTraceGeneral - 线程WriteDatabaseThread发生异常!错误编号:未指定的错误;错误描述: ORA-00001: 违反唯一约束条件 (OTDRUSER.STRACONSTANTINFO_PK)
6、原来数据库方面由于表数据的特殊性我之前未对所操作的表建立主键,导致后期人员维护时给添加了主键,从而导致数据插入失败。
7、与其沟通之后数据库方面对所操作的表采用了联合主键的方案来解决问题,之所以使用它是因为该表的CURTIME字段和POSITION字段都有可能会重复,异常数据都是以某一时刻成批量插入数据库的,所以这样使用联合主键既可以唯一标识每一条记录,又可以不影响POSITION值的重复。添加联合主键的SQL代码如下:
alter table STRACONSTANTINFO add constraints STRACONSTANTINFO_PK primary key (CURTIME,POSITION);
总结反思:
1、今后异常捕获写成统一格式,不再乱改,便于发现异常,处
理问题:
try
{
xxxxxxxx;
}
catch (_com_error e) //异常捕获:出现的异常为_com_error
{
CString errormessage = _T("");
errormessage.Format(_T("XXXXXXX发生异常!错误编号:%s;错误信息: %s;错误描述: %s\n"), e.Error(), e.ErrorMessage(),e.Description());
TRACE(errormessage);
}
2、对于ORACLE中的联合主键:
(1)由于网上对联合与复合主键的资料都有些乱。我个人理解,在oracle中,总之是添加了一个约束STRACONSTANTINFO_PK,这个约束中主键由CURTIME,POSITION组成。
(2)这个组合键中两个字段的值是可以重复的,但它们联合保证了唯一索引。
参考:https://blog.csdn.net/u011781521/article/details/71083112