ADO Recordset AddNew一直抛异常
2015-12-07 15:51
363 查看
如果你在某些方面是个小白,那你走每一步都很受挫。
最近公司做了一个XXX系统(C++),使用ADO连接数据库,系统实现之后发现,数据库的插入效率很是问题,10万条左右的记录用时9分多钟,当然不管是客户端还是服务器的配置都比较低,但应该也不至于速度如此之慢,网上搜了下,有些人的插入效率能达到每秒8000条,看着这些数据我也是醉了,于是,就想优化一下数据库的插入效率。
当然,我写这个的目的并不是说我的数据库是怎么优化的(最后还是没成功,优化为了10万条用时3分钟,每秒500条,比着8000条还是没法说的)。我的目的是想说一下ADO的记录集(RecordsetPrt)的AddNew()从不能用到能用的艰辛过程,如果你也遇到这种问题了,或许对你有帮助。
首先先交代一下背景,一开始插入数据库的操作是使用的ADO中的连接对象(ConnectPtr),然后通过将要插入的数据拼成SQL执行的方式来进行数据插入。由于插入效率太低,我准备改成使用记录集(RecordsetPtr)来进行插入处理。
上网搜了下,使用RecordsetPtr来插入时很简单,只要Open之后,AddNew,然后PutCollect,最后Update或者UpdateBatch就行了。于是照着葫芦画了个瓢,结果怎么都不行,一直在Support(adAddNew)的时候返回False,将Support注释之后,AddNew一直抛异常。
对于这个现象,我首先考虑的是,记录集的属性设置可能不对,于是又看了下网上的例子,对于打开时指定的参数(比如CursorType),我跟那些例子是一样的(①打开方式不能是Static的 ②不能是通过ConnectPtr或者CommandPtr调用Execute的到的记录集),从官网上看,需要AddNew时打开方式应该是adOpenKeyset,我实际测试时使用adOpenKeyset打开时返回的也是OK,而使用adOpenDynamic打开时虽然返回的不是不成功,但是返回了个ERROROCCURS(具体忘了)。
然后,网上又有人说,打开后需要将记录移到最后,于是我又在Open之后调用了MoveLast。结果在MoveLast的地方就抛异常了
然后,网上又有人说,需要再打开之后设置Connection->CursorLocation = adUseClient;(注意是ConnectPtr的属性),而我最后连RecordsetPtr的这个属性也设置了,最终还是不管用。
然后,我又从官网上了解到,提供者是否支持这个功能?于是我又将我的提供者(Provider)从Provider=MSDAORA.1改为了Provider=OraOLEDB.Oracle.1,结果还是不行。
然后,我又看到网上有人说,你必须在Open之后首先调用AddNew,不能调用其他的方法,我试着把我原来加上的MoveLast()调用删除,结果,令我震惊的是,AddNew能通过了。
我明明一开始就是首先调用的AddNew啊?怀着这个疑问,我又试了一下上面的改法,得出的结论如下:
① Connection->CursorLocation = adUseClient可能在别处有用,但不适用于我这种情况(对我的情况没有影响)。
② Open之后别的方法能不能调用我没试,但至少别调用MoveLast。
③ Provider是其他情况时我没试,但至少MSDAORA.1不行,而OraOLEDB.Oracle.1行。
一开始多种设定互相影响导致了执行不成功,让我产生了每个方法都不行的错觉,尤其是作为数据库小白的我,看不出其中的玄机,只能瞎猫去碰死耗子了。
最近公司做了一个XXX系统(C++),使用ADO连接数据库,系统实现之后发现,数据库的插入效率很是问题,10万条左右的记录用时9分多钟,当然不管是客户端还是服务器的配置都比较低,但应该也不至于速度如此之慢,网上搜了下,有些人的插入效率能达到每秒8000条,看着这些数据我也是醉了,于是,就想优化一下数据库的插入效率。
当然,我写这个的目的并不是说我的数据库是怎么优化的(最后还是没成功,优化为了10万条用时3分钟,每秒500条,比着8000条还是没法说的)。我的目的是想说一下ADO的记录集(RecordsetPrt)的AddNew()从不能用到能用的艰辛过程,如果你也遇到这种问题了,或许对你有帮助。
首先先交代一下背景,一开始插入数据库的操作是使用的ADO中的连接对象(ConnectPtr),然后通过将要插入的数据拼成SQL执行的方式来进行数据插入。由于插入效率太低,我准备改成使用记录集(RecordsetPtr)来进行插入处理。
上网搜了下,使用RecordsetPtr来插入时很简单,只要Open之后,AddNew,然后PutCollect,最后Update或者UpdateBatch就行了。于是照着葫芦画了个瓢,结果怎么都不行,一直在Support(adAddNew)的时候返回False,将Support注释之后,AddNew一直抛异常。
对于这个现象,我首先考虑的是,记录集的属性设置可能不对,于是又看了下网上的例子,对于打开时指定的参数(比如CursorType),我跟那些例子是一样的(①打开方式不能是Static的 ②不能是通过ConnectPtr或者CommandPtr调用Execute的到的记录集),从官网上看,需要AddNew时打开方式应该是adOpenKeyset,我实际测试时使用adOpenKeyset打开时返回的也是OK,而使用adOpenDynamic打开时虽然返回的不是不成功,但是返回了个ERROROCCURS(具体忘了)。
然后,网上又有人说,打开后需要将记录移到最后,于是我又在Open之后调用了MoveLast。结果在MoveLast的地方就抛异常了
然后,网上又有人说,需要再打开之后设置Connection->CursorLocation = adUseClient;(注意是ConnectPtr的属性),而我最后连RecordsetPtr的这个属性也设置了,最终还是不管用。
然后,我又从官网上了解到,提供者是否支持这个功能?于是我又将我的提供者(Provider)从Provider=MSDAORA.1改为了Provider=OraOLEDB.Oracle.1,结果还是不行。
然后,我又看到网上有人说,你必须在Open之后首先调用AddNew,不能调用其他的方法,我试着把我原来加上的MoveLast()调用删除,结果,令我震惊的是,AddNew能通过了。
我明明一开始就是首先调用的AddNew啊?怀着这个疑问,我又试了一下上面的改法,得出的结论如下:
① Connection->CursorLocation = adUseClient可能在别处有用,但不适用于我这种情况(对我的情况没有影响)。
② Open之后别的方法能不能调用我没试,但至少别调用MoveLast。
③ Provider是其他情况时我没试,但至少MSDAORA.1不行,而OraOLEDB.Oracle.1行。
一开始多种设定互相影响导致了执行不成功,让我产生了每个方法都不行的错觉,尤其是作为数据库小白的我,看不出其中的玄机,只能瞎猫去碰死耗子了。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 如何重装TCP/IP协议
- 关于指针的一些事情
- Windows 8 官方高清壁纸欣赏与下载
- 谁是桌面王者?Win PK Linux三大镇山之宝
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows Clang开发环境备忘
- 从Windows系统下访问Linux分区相关软件
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- Windows下搭建本地SVN服务器
- c++ primer 第五版 笔记前言
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- Visual Studio 2012 示例代码浏览器 - 数以千计的开发示例近在手边,唾手可得
- share_ptr的几个注意点
- 微软镜像下载
- windows server域用户提升到本地更高权限组中的方法
- 使用命令修改注册表键值及权限
- 通过手机、电脑远程开关机,Windows和linux机手机,电脑相互控制