您的位置:首页 > 编程语言 > C语言/C++

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行。

    一开始多种设定互相影响导致了执行不成功,让我产生了每个方法都不行的错觉,尤其是作为数据库小白的我,看不出其中的玄机,只能瞎猫去碰死耗子了。

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows ADO C++ AddNew 异常