楼主: yulihua49

[PRO*C] 看我做的数据库包装器

[复制链接]
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
111#
发表于 2008-12-13 02:09 | 只看该作者


根据你的意见修改如下,结果和修改前区别不大,最长的JOB 花了8.57秒,最短的0.74秒:

CREATE OR REPLACE PROCEDURE getseat_for_sell3 (
                            p_result      OUT SYS_REFCURSOR     ---- 结果集
                           ,p_count       OUT NUMBER            ---- 获得的票数。假如没有足够的票, 可能<p_quantity
                           ,p_start_date  IN  DATE
                           ,p_train_no    IN  VARCHAR2
                           ,p_beg_station IN  VARCHAR2
                           ,p_arrive      IN  NUMBER
                           ,p_xb          IN  NUMBER
                           ,p_purpose     IN  NUMBER
                           ,p_quantity    IN  NUMBER
                           ,p_userid      IN  VARCHAR2
                           ,p_devid       IN  VARCHAR2
                            )
AS
   e_locked      EXCEPTION;
   PRAGMA EXCEPTION_INIT (e_locked, -54);
   lv_result tp_seat_table2 := tp_seat_table2();
   lv_rec  seat%ROWTYPE;
BEGIN
   p_count := 0;
   
   FOR lv_r   IN (SELECT rowid AS row_id
                    FROM seat
                   WHERE start_date        = p_start_date
                         AND beg_station   = p_beg_station
                         AND train_no      = p_train_no
                         AND (MOD(p_xb,10) = 0 AND seat_type > p_xb AND seat_type <= p_xb+9
                              OR MOD(p_xb,10) <> 0 AND seat_type = p_xb
                              )
                         AND end_station  >= p_arrive
                         AND purpose      =  p_purpose
                         AND flag         =  0
                   ORDER BY end_station,carno,seat_no,seat_type*DECODE(p_xb,0,-1,1)
                 )
   LOOP
      
       BEGIN
          SELECT *
            INTO lv_rec
            FROM seat
           WHERE rowid = lv_r.row_id
                 AND flag = 0
           FOR UPDATE NOWAIT;
       EXCEPTION
          WHEN e_locked OR NO_DATA_FOUND THEN
               lv_rec.flag := NULL;
       END;
      
       IF lv_rec.flag = 0 THEN
          UPDATE seat
             SET flag      =1
                ,used_time = SYSDATE
                ,used_uid  = p_userid
                ,used_dev  = p_devid
           WHERE rowid = lv_r.row_id;

          p_count := p_count+1;
          lv_result.EXTEND;
          lv_result(p_count) := tp_seat2(TO_CHAR(lv_rec.start_date,'YYYY-MM-DD')
                                        ,lv_rec.beg_station
                                        ,lv_rec.train_no
                                        ,lv_rec.run_train
                                        ,TO_CHAR(lv_rec.on_date,'YYYY-MM-DD HH24:MI')
                                        ,lv_rec.carno
                                        ,lv_rec.seat_type
                                        ,lv_rec.seat_no
                                        ,lv_rec.end_station
                                        ,lv_rec.shortest_station
                                        ,lv_rec.purpose
                                        ,lv_rec.gride
                                        ,lv_rec.pro
                                        ,lv_rec.flag
                                        ,lv_rec.used_dev
                                        ,lv_rec.used_uid
                                        ,TO_CHAR(lv_rec.used_time,'YYYY-MM-DD HH24:MI:SS')
                                        ,ROWIDTOCHAR(lv_r.row_id)
                                       );
         
          IF p_count >= p_quantity THEN
             EXIT;
          END IF;
       END IF;
   END LOOP;
   
   OPEN p_result FOR
   SELECT *               
     FROM TABLE(CAST(lv_result AS tp_seat_table2)) r
   ORDER BY end_station,carno,seat_no,seat_type*DECODE(p_xb,0,-1,1);
   
END getseat_for_sell3;
/


使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
112#
发表于 2008-12-13 04:29 | 只看该作者
关于那个“席位生成程序”,我只看到了SELECT, INSERT在哪里?不知道你是怎么循环的(不至于每张票都INSERT一下吧?),但是实际上你没有必要“每天所有车次各种席位反复调用”,即使车次、席位各不相同,一个INSERT....SELECT....就可代替你的循环。

关于“不会用ROWID做持久化对象”,我猜你的意思是不会UPDATE ROWID?这个改变来自ORACLE,不是你能控制得了的。ROWID被改动的情况我前面说了。除了那些情形,你EXP再IMP,ROWID也会完全不同。所以说,超出一个事务,你如果再试图使用ROWID来定位数据那就非常不合理了。

使用道具 举报

回复
论坛徽章:
33
劳斯莱斯
日期:2013-08-08 14:01:23三菱
日期:2013-09-28 10:16:06一汽
日期:2013-11-19 17:01:11凯迪拉克
日期:2013-12-07 17:11:282014年新春福章
日期:2014-02-18 16:42:02马上有房
日期:2014-02-18 16:42:02itpub13周年纪念徽章
日期:2014-09-27 14:20:21itpub13周年纪念徽章
日期:2014-10-08 15:13:38懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
113#
发表于 2008-12-13 08:44 | 只看该作者

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
114#
 楼主| 发表于 2008-12-14 15:02 | 只看该作者
原帖由 newkid 于 2008-12-13 00:10 发表
我怀疑你们的参数是这么设置的:cursor_sharing = force 或者 similar
这个开关是专门应付你们这种设计方法的,但有其副作用,最好不用。



  这个我不是太清楚,请明示。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
115#
 楼主| 发表于 2008-12-14 15:09 | 只看该作者
原帖由 newkid 于 2008-12-13 04:29 发表
关于那个“席位生成程序”,我只看到了SELECT, INSERT在哪里?不知道你是怎么循环的(不至于每张票都INSERT一下吧?),但是实际上你没有必要“每天所有车次各种席位反复调用”,即使车次、席位各不相同,一个INSERT....SELECT....就可代替你的循环。

关于“不会用ROWID做持久化对象”,我猜你的意思是不会UPDATE ROWID?这个改变来自ORACLE,不是你能控制得了的。ROWID被改动的情况我前面说了。除了那些情形,你EXP再IMP,ROWID也会完全不同。所以说,超出一个事务,你如果再试图使用ROWID来定位数据那就非常不合理了。

我的框架不修改ROWID,你看我前边生成的update语句,有ROWID吗?
ROWID肯定跨事务,但其生命期内不可能重建数据库,或重载数据。
我当然没给你全部代码,只给了一句话。
另外,使用那个绑定语句,游标是不能关闭的,只能一次又一次的 reopen ,这让我很不爽。

到现在为止,我仍然不认为绑定不绑定变量,开销上的区别有多大。
尤其是简单语句,ORACLE如此高明,以至于语句分析的开销,你根本察觉不出。
下周,我打算测试一下到底语句分析有多大开销。
整个SQL的开销,相当大的仍然是语句的执行,尤其是那些decode函数,还有其他函数。

[ 本帖最后由 yulihua49 于 2008-12-14 15:18 编辑 ]

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
116#
发表于 2008-12-15 00:05 | 只看该作者
到现在为止,我仍然不认为绑定不绑定变量,开销上的区别有多大??

你这句话有很大的问题!!建议深入研究一下oracle,也许目前你们做的能满足业务的需求,但是当业务的需求更复杂的时候,你们做的驾驭不了的时候,你就知道绑定变量的作用了,这个可以看看tom的讲解!~人家会教你为什么使用绑定变量和为什么不要滥用绑定变量!

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
117#
发表于 2008-12-15 07:55 | 只看该作者
"这个我不是太清楚,请明示。"
用DBA登录SQLPLUS然后 SHOW PARAMETER CURSOR_SHARING
关于这个参数的用法可参考文档,它会把常量自动转化为绑定变量,但有些不该转的也转了变成所谓的OVER BIND。


"我的框架不修改ROWID,你看我前边生成的update语句,有ROWID吗?"
我当然知道,我也没说你UPDATE ROWID. 我的语文表达能力真那么差吗?

"ROWID肯定跨事务,但其生命期内不可能重建数据库,或重载数据。"
不要那么绝对,那天你需要从逻辑备份作灾难恢复,你的ROWID就全部变了,那时你可就欲哭无泪。
此外数据还会被复制到CRM, 数据仓库等地方,你的ROWID也全变了。用ROWID作主键是你所有错误中最低级的一个。

"我当然没给你全部代码,只给了一句话。"
你语焉不详我倒更有兴趣了,到底是怎么INSERT的?
到目前为止,你暴露的源代码或多或少都被我挑过毛病,不要怕,我这是免费义诊。

"另外,使用那个绑定语句,游标是不能关闭的,只能一次又一次的 reopen ,这让我很不爽。"
谁说的要REOPEN? 一个游标就是用到事务结束,数据全取出来了就关闭。你生成不同的SQL, 反而不需要REOPEN了?

"到现在为止,我仍然不认为绑定不绑定变量,开销上的区别有多大。
尤其是简单语句,ORACLE如此高明,以至于语句分析的开销,你根本察觉不出。
下周,我打算测试一下到底语句分析有多大开销。"
我给你的TOM的书链接中有很好的测试例子,你好好看一下。记得要用ROWID作大量测试,这是最能看出区别的。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
118#
 楼主| 发表于 2008-12-15 14:57 | 只看该作者
原帖由 newkid 于 2008-12-15 07:55 发表
"ROWID肯定跨事务,但其生命期内不可能重建数据库,或重载数据。"
不要那么绝对,那天你需要从逻辑备份作灾难恢复,你的ROWID就全部变了,那时你可就欲哭无泪。
此外数据还会被复制到CRM, 数据仓库等地方,你的ROWID也全变了。用ROWID作主键是你所有错误中最低级的一个。


"另外,使用那个绑定语句,游标是不能关闭的,只能一次又一次的 reopen ,这让我很不爽。"
谁说的要REOPEN? 一个游标就是用到事务结束,数据全取出来了就关闭。你生成不同的SQL, 反而不需要REOPEN了?

"到现在为止,我仍然不认为绑定不绑定变量,开销上的区别有多大。
尤其是简单语句,ORACLE如此高明,以至于语句分析的开销,你根本察觉不出。
下周,我打算测试一下到底语句分析有多大开销。"
我给你的TOM的书链接中有很好的测试例子,你好好看一下。记得要用ROWID作大量测试,这是最能看出区别的。

我不会在那种场合使用ROWID,只在这个流程里用。你放心吧,什么时候能用ROWID,什么时候不能用我清楚。

关闭游标的问题是OCI的问题,我们不讨论。

我要在OCI环境下测。
现在有了第一部分的结果,是不绑定的:

5 ./loadasc:5576 12/15 14:35'15 tabname=tjrb
5 ./loadasc:5576 12/15 14:35'15 ___SQL_OpenDatabase__: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
5 ./loadasc:5576 12/15 14:35'15 DB=TICKET
5 ./loadasc:5576 12/15 14:35'15 loadfile:entry
5 ./loadasc:5576 12/15 14:35'15 mkpk:tjdate|unit|tabname|flg|
2 ./loadasc:5576 12/15 14:35'21 loadfile:rows=3776,upd=0,loss=0
//空库添加数据。上午还是2秒,下午不知为什么变6秒了,在IBM H70 SYBASE上是30多秒。
2 ./loadasc:5576 12/15 14:35'21 loadasc:load 3776 rec's time=6,buf=INSERT INTO TICKET.TJRB (tjdate,unit,tabname,flg,dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16,dat17,dat18,dat19,dat20,dat21,dat22,dat23,dat24,dat25,dat26,dat27,dat28,dat29,dat30,dat31,dat32,dat33,dat34,dat35,dat36,dat37,dat38,dat39,dat40,dat41,dat42,dat43,dat44,dat45,dat46,dat47,dat48,dat49,dat50) VALUES (to_date('2007.01.31','YYYY-MM-DD HH24:MI:SS'),'55','A7',102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
5 ./loadasc:5587 12/15 14:38'34 tabname=tjrb
5 ./loadasc:5602 12/15 14:40'20 tabname=tjrb
5 ./loadasc:5602 12/15 14:40'20 ___SQL_OpenDatabase__: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
5 ./loadasc:5602 12/15 14:40'20 DB=TICKET
5 ./loadasc:5602 12/15 14:40'20 loadfile:entry
5 ./loadasc:5602 12/15 14:40'20 mkpk:tjdate|unit|tabname|flg|
//加载时发生重码,进行update,反而比纯粹的insert快
2 ./loadasc:5602 12/15 14:40'24 loadfile:rows=0,upd=3776,loss=0
2 ./loadasc:5602 12/15 14:40'24 loadasc:load 0 rec's time=4,buf=UPDATE TICKET.TJRB SET(tjdate,unit,tabname,flg,dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16,dat17,dat18,dat19,dat20,dat21,dat22,dat23,dat24,dat25,dat26,dat27,dat28,dat29,dat30,dat31,dat32,dat33,dat34,dat35,dat36,dat37,dat38,dat39,dat40,dat41,dat42,dat43,dat44,dat45,dat46,dat47,dat48,dat49,dat50)=(SELECT to_date('2007.01.31','YYYY-MM-DD HH24:MI:SS'),'55','A7',102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 FROM DUAL) WHERE tjdate = to_date('2007.01.31','YYYY-MM-DD HH24:MI:SS') AND unit = '55' AND tabname = 'A7' AND flg = 102
5 ./loadasc:5609 12/15 14:42'19 tabname=tjrb5 ./loadasc:5609 12/15 14:42'19 ___SQL_OpenDatabase__: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit ProductionWith the Partitioning, OLAP and Data Mining options5 ./loadasc:5609 12/15 14:42'19 DB=TICKET5 ./loadasc:5609 12/15 14:42'19 loadfile:entry
5 ./loadasc:5609 12/15 14:42'19 mkpk:tjdate|unit|tabname|flg|
//加载时发生重码,丢掉。不知为何如此慢。
2 ./loadasc:5609 12/15 14:44'48 loadfile:rows=0,upd=0,loss=3776
2 ./loadasc:5609 12/15 14:44'48 loadasc:load 0 rec's time=149,buf=INSERT INTO TICKET.TJRB (tjdate,unit,tabname,flg,dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16,dat17,dat18,dat19,dat20,dat21,dat22,dat23,dat24,dat25,dat26,dat27,dat28,dat29,dat30,dat31,dat32,dat33,dat34,dat35,dat36,dat37,dat38,dat39,dat40,dat41,dat42,dat43,dat44,dat45,dat46,dat47,dat48,dat49,dat50) VALUES (to_date('2007.01.31','YYYY-MM-DD HH24:MI:SS'),'55','A7',102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0):err=1,ORA-00001: unique constraint (TICKET.SYS_C0011534) violated

[ 本帖最后由 yulihua49 于 2008-12-15 15:18 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
119#
 楼主| 发表于 2008-12-15 15:11 | 只看该作者
原帖由 newkid 于 2008-12-15 07:55 发表
"这个我不是太清楚,请明示。"
用DBA登录SQLPLUS然后 SHOW PARAMETER CURSOR_SHARING
关于这个参数的用法可参考文档,它会把常量自动转化为绑定变量,但有些不该转的也转了变成所谓的OVER BIND。


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT

上边结果,其程序是:
loadasc.c
是一个万能加载程序,加载ASCII码的数据到数据库。这是个完全新写的程序,原来有一个类似的,没使用DAU。
这次用DAU做,全通用的,可以加载任何数据。你只要看loadfile()就行了,其他代码供参考。

#include <stdio.h>
#define SERVER
//#include <sdbc.h>
#include <DAU_utility.h>
#include <ctype.h>

#define trans_begin(SQL_Connect)  ___SQL_Transaction__(SQL_Connect,TRANBEGIN)
#define trans_rollback(SQL_Connect)  ___SQL_Transaction__(SQL_Connect,TRANROLLBACK)
#define trans_commit(SQL_Connect)  ___SQL_Transaction__(SQL_Connect,TRANCOMMIT)

static int mkwhere(SRM *srmp,char *where)
{
char *pks,*p,*p1;
char kbuf[31];
int i;
T_PkgType Char_Type[2];
        if(!srmp||!where) return 0;
        if(srmp->pkn<=0 || !srmp->pks) {
                return 0;
        }
        *where=0;
        pks=strdup(srmp->pks);
        p=pks;
        Char_Type[0].type=CH_CHAR;
        Char_Type[0].len=-1;
        Char_Type[0].offset=0;
        Char_Type[1].type=-1;
        Char_Type[1].len=0;
        p1=where;
        p1+=sprintf(p1,"WHERE ";
        for(i=0;i<srmp->pkn;i++) {
                if(i>0) p1+=sprintf(p1," AND ";
                p+=net_dispack(kbuf,p,Char_Type);
                p1+=SRM_mkcond(srmp,p1,kbuf,"=";
        }
        free(pks);
        return strlen(where);
}


static int updaterec(DAU *DP,char *buf)
{
int ret;

        ret=mkwhere(&DP->srm,buf);
        if(!ret)  return -1;

        ret=DAU_update(DP,buf);
        if(ret<=0) {
                ShowLog(1,"updaterec:%s",buf);
        }
        return ret;
}

int loadfile(T_SQL_Connect *SQL_Connect,char *tabname,FILE *ifd,FILE *ofd,int Pflg,char *buf,int buflen)
{
char *p,tabn[512];
DAU _DAU;
int rows,ret;
int upd,loss;

        ShowLog(5,"loadfile:entry";
        if(tabname) {
                ret=DAU_init(&_DAU,SQL_Connect,tabname,0,0);
                if(ret) {
                        ShowLog(1,"loadfileAU_init tabname=%s,ret=%d",tabname,ret);
                        return -1;
                }
        }
        upd=loss=0;
        for(rows=0;!ferror(ifd);rows++) {
                fgets(buf,buflen,ifd);
                if(feof(ifd)) break;
                TRIM(buf);
                if(!*buf) {
                        rows--;
                        continue;
                }
                if(rows==0 && !tabname) {
                        p=skipblk(buf);
                        ret=sscanf(p,"TABNAME=%s",tabn);
                        if(ret<1) {
                                ShowLog(1,"Can Not find TABLE Name!";
                                return FORMATERR;
                        }
                        ret=DAU_init(&_DAU,SQL_Connect,tabn,0,0);
                        if(ret) {
                                ShowLog(1,"loadfileAU_init tabname=%s",tabn);
                                return -1;
                        }
                        continue;
                }
                DAU_dispack(&_DAU,buf);
                ret=DAU_insert(&_DAU,buf);
                if(ret) {
                        if(SQL_Connect->Errno == DUPKEY) {
                                if(!Pflg) {//如果没有-P选项
                                        ret=updaterec(&_DAU,buf);
                                        if(ret==1) upd+=ret;
                                        else loss++;
                                }
                                else loss++;
                        } else {
                                DAU_pack(&_DAU,buf);
                                fprintf(ofd,"%s\n",buf);
                                ShowLog(1,"loadfile:%s",buf);
                                loss++;
                        }
                        rows--;
                        continue;
                }
        }
        DAU_free(&_DAU);
        ShowLog(2,"loadfile:rows=%d,upd=%d,loss=%d",rows,upd,loss);
        return rows;
}

static char my_showid[200];
main(int argc,char *argv[])
{
int ret,i;
T_SQL_Connect SQL_Connect;
int Pflg=0;
char *tabname=0;
FILE *ifd,*ofd;
INT64 now;
char buf[4096];//最大数据长度有限

        tzset();
        sprintf(my_showid,"%s:%d",
                argv[0],getpid());
        Showid=my_showid;
        ifd=0;
        ofd=0;

/*******************************************************************
*  get Opt
*******************************************************************/
        for(i=1;i<argc;i++) {
                if(*argv=='-') {
                        switch(argv[1]) {
                        case 'f':
                                if(argv[2]) ret=envcfg(argv+2);
                                else {
                                        i++;
                                        ret=envcfg(argv);
                                }
                                continue;
                        case 'P':  //输出 不能加载的记录
                                Pflg=1;
                                if(argv[2]) {
                                        ofd=fopen(argv+2,"w";
                                } else {
                                        i++;
                                        if(i<argc) ofd=fopen(argv,"w";
                                }
                                continue;

        Showid=my_showid;
        ifd=0;
        ofd=0;

/*******************************************************************
*  get Opt
*******************************************************************/
        for(i=1;i<argc;i++) {
                if(*argv=='-') {
                        switch(argv[1]) {
                        case 'f':
                                if(argv[2]) ret=envcfg(argv+2);
                                else {
                                        i++;
                                        ret=envcfg(argv);
                                }
                                continue;
                        case 'P':  //输出 不能加载的记录
                                Pflg=1;
                                if(argv[2]) {
                                        ofd=fopen(argv+2,"w";
                                } else {
                                        i++;
                                        if(i<argc) ofd=fopen(argv,"w";
                                }
                                continue;

                        default:
                                fprintf(stderr,"no know option:%s",argv);
                                fprintf(stderr,"Usage:%s -f 配置文件 [-P]  输出文件名 ",
                                        argv[0]);
                                continue;
                        }
                }
                tabname=argv;
        }

ShowLog(5,"tabname=%s",tabname);
        ret=db_open(&SQL_Connect);
        if(ret) {
                ShowLog(1,"Open Database err=%d.%s",
                        SQL_Connect.Errno,
                        SQL_Connect.ErrMsg);
                return 1;
        }
ShowLog(5,"DB=%s",SQL_Connect.DBOWN);
        if(!ofd) ofd=stdout;
        ifd=stdin;

        now=now_sec();
        ret=loadfile(&SQL_Connect,tabname,ifd,ofd,Pflg,buf,sizeof(buf));
        ShowLog(2,"loadasc:load %d rec's time=%d,buf=%s",ret,(int)(now_sec()-now),buf);
        trans_commit(&SQL_Connect);

        if(ofd && ofd != stdout) fclose(ofd);
        ret=___SQL_CloseDatabase__(&SQL_Connect);
        return 0;
}

[ 本帖最后由 yulihua49 于 2008-12-15 15:15 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
120#
 楼主| 发表于 2008-12-15 15:22 | 只看该作者
这是表结构,统计日报,就是我前边说的万能统计表。

drop table tjrb;
create table tjrb (
        tjdate date     not null, //统计日期
        unit varchar(8) not null, //单位
        tabname varchar(8) not null,//表名
        flg     number(3), //标记
        dat1    number(15),
        dat2    number(15),
        dat3    number(15),
        dat4    number(15),
        dat5    number(15),
        dat6    number(15),
        dat7    number(15),
        dat8    number(15),
        dat9    number(15),
        dat10   number(15),
        dat11   number(15),
        dat12   number(15),
        dat13   number(15),
        dat14   number(15),
        dat15   number(15),
        dat16   number(15),
        dat17   number(15),
        dat18   number(15),
        dat19   number(15),
        dat20   number(15),
        dat21   number(15),
        dat22   number(15),
        dat23   number(15),
        dat24   number(15),
        dat25   number(15),
        dat26   number(15),
        dat27   number(15),
        dat28   number(15),
        dat29   number(15),
        dat30   number(15),
        dat31   number(15),
        dat32   number(15),
        dat33   number(15),
        dat34   number(15),
        dat35   number(15),
        dat36   number(15),
        dat37   number(15),
        dat38   number(15),
        dat39   number(15),
        dat40   number(15),
        dat41   number(15),
        dat42   number(15),
        dat43   number(15),
        dat44   number(15),
        dat45   number(15),
        dat46   number(15),
        dat47   number(15),
        dat48   number(15),
        dat49   number(15),
        dat50   number(15),
        primary key (tjdate,unit,tabname,flg)
);

你看前边那个loadfile(),一共没有几行,就解决了通用数据加载问题,没有显式使用模板,完全是自动生成的。一个SQL也没有。
至于无法解释的执行时间问题,我看完全是ORACLE的问题,我不知它是如何做的。

就加入新数据而言,速度够快了,我的环境就是个HP的PC服务器,IA64的。
没有感觉SQL语句解析的开销。
但,使用绑定变量的程序我还是要试一下。

数据在此,你可以试一下。

[ 本帖最后由 yulihua49 于 2008-12-15 15:35 编辑 ]

TJ01.rar

146.9 KB, 下载次数: 14

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表