楼主: 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
271#
发表于 2009-3-6 00:01 | 只看该作者
原帖由 nyfor 于 2009-3-5 14:02 发表
据 Oracle 文档介绍, Pro*C 使用的并非是 OCI (也许最终使用的是 OCI 吧), 它使用的是依赖于 Oracle 版本的 SQLLIB 库, 当然 Pro*C 中也可以直接调用 OCI.  

非常佩服本帖中两位的针锋讨论.

楼主在这个版块发这样的帖子, 引来的必定是一片的质疑声(包括我).

我觉得楼主不应该强调你的包装器的性能, 或许你应该强调的是使用你的包装器带来的开发效率(当然对于不太了解Oracle,不太了解SQL的程序员来说).

通看整片帖子的过程中, 我曾想起过以下词句(只当做调侃,别无它意): 龙芯一号, 汉语编程, 方舟子.

诚然, 对于楼主的包装器它固然也有它的优点(那些优点对于精于Oracle数据库编程的人员来说可能完全是缺点).

把这贴再顶起来, 另外建议 newkid 以本为内容发布一新帖, 不给你加一个精华, 实在是.....


呵呵,都是些老生常谈,不值得加精华。
楼主的研发精神是可嘉的,用的又不是国家的经费,所以和打磨芯片不可混为一谈。他的作品对于他原来那套编程方法肯定是有帮助的, 我只是试图让他相信还有更好的编程方法。当然这很不容易,俗话说老婆是别人的好,程序是自己的好!

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
272#
发表于 2009-3-6 09:47 | 只看该作者
原帖由 newkid 于 2009-3-6 00:01 发表
俗话说老婆是别人的好,程序是自己的好!


太谦虚了,呵呵.

另外楼主加油, 等着看你们新一轮的擂台呢....

使用道具 举报

回复
论坛徽章:
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
273#
 楼主| 发表于 2009-3-6 11:10 | 只看该作者
原帖由 newkid 于 2009-3-3 05:37 发表
在你#272贴的帮助下把程序看懂了。现在我只需要你的数据结构作最后的确认。
你这个程序只能发布一天的吗?最好能把需求改为发布一个日期区间的。数据量越大越能体现SQL的优势。
实际应用中重复发布的情况多不多?如果不多的话我就只考虑INSERT就够了,用不上MERGE。

程序调通了,原来那个程序还是有点错误的,语法错误,逻辑基本还是对的。
发布一下当日的,由于今天夜里已发布过,失败的,由于有了dummy_update,仅用:(原来要好几分钟呢)
tuxticket@jgbticket:~/test> time ./xwfb.sh

real    0m2.290s
user    0m0.268s
sys     0m0.124s
发布明天的,-D+1就是明天,成功5156个席位。原来6秒,不用DAU,也没有bind。
tuxticket@jgbticket:~/test> time ./xwfb.sh -D+1

real    0m1.656s
user    0m0.184s
sys     0m0.104s

  1. 5 xwfbDAU:2930 03/06 10:50'17 xwfb gettrain:train_no=H1,beg_date=2008.02.01,end_date=2099.12.31,jobday=2009-03-17,i_item=1
  2. 5 xwfbDAU:2930 03/06 10:50'17 bind_ins:sth=0,stmt=INSERT INTO TICKET.SEAT (start_date,beg_station,train_no,run_train,on_date,carno,seat_type,seat_no,end_station,shortest_station,purpose,gride,pro,flag,used_dev,used_uid,used_time) VALUES (to_date(:1,'YYYY-MM-DD'), :2, :3, :4,to_date(:5,'YYYY-MM-DD HH24:MI'), :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16,to_date(:17,'YYYY-MM-DD HH24:MI:SS'))
  3. 2 xwfbDAU:2930 03/06 10:50'17 train=2009-03-17;H1,carno=0,beg_station=YZHP,end_station=5,remant=30
  4. 5 xwfbDAU:2930 03/06 10:50'17 bind_prepare:cursor=1,SELECT  to_char(on_date,'YYYY-MM-DD') on_date,beg_station,run_train,carno,seat_type,purpose,end_station,amoung FROM TICKET.SEAT_REMANT WHERE on_date=to_date(:1,'YYYY-MM-DD') AND beg_station=:2 AND run_train=:3 AND carno=:4 AND seat_type=:5 AND purpose=:6 AND end_station=:7 for update
  5. 5 xwfbDAU:2930 03/06 10:50'17 bind_ins:sth=2,stmt=INSERT INTO TICKET.SEAT_REMANT (on_date,beg_station,run_train,carno,seat_type,purpose,end_station,amoung) VALUES (to_date(:1,'YYYY-MM-DD'), :2, :3, :4, :5, :6, :7, :8)
  6. 2 xwfbDAU:2930 03/06 10:50'17 train=2009-03-17;H1,carno=0,beg_station=YLHP,end_station=5,remant=30
  7. 5 xwfbDAU:2930 03/06 10:50'17 bind_ins:sth=3,stmt=INSERT INTO TICKET.SEAT (start_date,beg_station,train_no,run_train,on_date,carno,seat_type,seat_no,end_station,shortest_station,purpose,gride,pro,flag,used_dev,used_uid,used_time) VALUES (to_date(:1,'YYYY-MM-DD'), :2, :3, :4,to_date(:5,'YYYY-MM-DD HH24:MI'), :6, :7, :8, :9, :10, :11, :12, :13, :14, :15, :16,to_date(:17,'YYYY-MM-DD HH24:MI:SS'))
  8. 2 xwfbDAU:2930 03/06 10:50'17 mkxw train=2009-03-17:H1,beg_station=BNHP,end_station=5,carno=1,remant=120
  9. 5 xwfbDAU:2930 03/06 10:50'17 bind_prepare:cursor=4,SELECT  to_char(on_date,'YYYY-MM-DD') on_date,beg_station,run_train,carno,seat_type,purpose,end_station,amoung FROM TICKET.SEAT_REMANT WHERE on_date=to_date(:1,'YYYY-MM-DD') AND beg_station=:2 AND run_train=:3 AND carno=:4 AND seat_type=:5 AND purpose=:6 AND end_station=:7 for update
  10. 5 xwfbDAU:2930 03/06 10:50'17 bind_ins:sth=5,stmt=INSERT INTO TICKET.SEAT_REMANT (on_date,beg_station,run_train,carno,seat_type,purpose,end_station,amoung) VALUES (to_date(:1,'YYYY-MM-DD'), :2, :3, :4, :5, :6, :7, :8)
  11. 5 xwfbDAU:2930 03/06 10:50'17 bind_update:bind=4,sth=6,stmt=UPDATE TICKET.PRE_SEAT_INDEX  SET distribute_time=to_date(:1,'YYYY-MM-DD HH24:MI:SS') WHERE train_no=:2 AND item=:3 AND end_date=to_date(:4,'YYYY-MM-DD'),


  12. 2 xwfbDAU:2930 03/06 10:50'19 totalnum=5156
  13. 补充语句:
  14. 2 xwfb:21149 03/04 02:00'01 stmt=select Train_no,to_char(beg_date,'YYYY-MM-DD') beg_date,to_char(end_date,'YYYY-MM-DD') end_date,start_station,end_station,station_num,total_distance,start_time,iterms,cycle,gride,price_mode,discount_mode,days,flag,owner,note from TICKET.train where flag=0 and end_date >= to_date('2009-03-04','YYYY-MM-DD')
  15. 5 xwfb:21149 03/04 02:00'01 xwfb gettrain:Train_no=H1,beg_date=2008.02.01,end_date=2099.12.31,jobday=2009-03-14,i_item=1
  16. 5 xwfb:21149 03/04 02:00'01 查找停靠站表 stmt=select Train_no,run_Train_no,sequence,to_char(beg_date,'YYYY-MM-DD') beg_date,to_char(end_date,'YYYY-MM-DD') end_date,station_code,distance,running_time,stop_time,over,flag from TICKET.stop_station where train_no='H1'  and beg_date <= to_date('2009-03-14','YYYY-MM-DD') and end_date >= to_date('2009-03-14','YYYY-MM-DD') and over>0 ,ret=2
  17. 5 xwfbDAU:3715 03/06 13:56'52 xwfb:SELECT  train_no,item,to_char(beg_date,'YYYY-MM-DD') beg_date,to_char(end_date,'YYYY-MM-DD') end_date,flag,to_char(distribute_time,'YYYY-MM-DD HH24:MI:SS') distribute_time,note FROM TICKET.PRE_SEAT_INDEX WHERE train_no=:1 AND item=:2 AND beg_date <= to_date(:3,'YYYY-MM-DD') AND end_date >= to_date(:4,'YYYY-MM-DD') AND flag=0

  18. 那个pre_seat,就是: where pre_id=:pre_id


复制代码
  1. //* default with not null */
  2. /* 母表分为母表索引和母表两部分如下:*/

  3. drop table pre_seat_index;
  4. create table pre_seat_index (           -- 母表索引
  5.         Train_no varchar2(12),  -- 全车次
  6.         item    char(1) default '1',-- 组号,一般='1'
  7.         beg_date date,  -- 有效起始日期 YYYY-MM-DD
  8.         end_date date,  -- 有效结束日期 YYYY-MM-DD
  9.         flag    number(1), --* 0:有效,其它:无效
  10.         distribute_time date null, -- 最后发布时间 YYYY-MM-DD HH24:MI:SS
  11.         note    varchar(20),
  12.         primary key (Train_no,item,end_date)
  13. );
  14. drop table pre_seat;
  15. create table pre_seat ( --  母表
  16.         Pre_ID varchar2(23), -- 索引,由pre_seat_index里的字段拼凑而来:
  17. -- Train_no:itam:beg_date(YYYYMMDD)
  18.         Carno number(2), -- 车厢号,不分车厢的票车厢号=0
  19.         seat_type number(4),  --席别,0=无号
  20.         beg_seatno number(3), -- 开始席号
  21.         end_seatno number(3),-- 结束席号
  22.         beg_station number(3), -- 上车站
  23.         end_station number(3),  -- 最远站
  24.         shortest_station number(3),  -- 限售以远
  25.         purpose number(9),              -- 用途
  26.         gride   varchar2(50),   -- 事由码,新空调直达特快等。
  27.         primary key (Pre_ID,Carno,beg_seatno,beg_station)
  28. );

  29. drop table seat;
  30. create table seat (             /* 席位表 */
  31.         start_date      date,   /* 始发日期 YYYY-MM-DD*/
  32.         beg_station varchar2(4),        /* 上车站略码 */
  33.         Train_no varchar2(12),  /* 全车次 */
  34.         run_train       varchar2(6),    /* 运行车次 */
  35.         on_date date,           /* 上车日期 YYYY-MM-DD HH24:MI*/
  36.         Carno number(2),        /* 车厢号,不分车厢的票车厢号=0 */
  37.         seat_type number(2),    /*席别,0=无号*/
  38.         seat_no   number(3),    /* 席位号 */
  39.         end_station number(3),  /* 顺号,售前是最远站,售后改为下车站 */
  40.         shortest_station number(3),     /* 顺号,限售以远 */
  41.         purpose number(9),              /* 用途 */
  42.         gride   varchar2(50),   -- 事由码,新空调直达特快等。
  43.         pro     char(5) null,   -- 席位属性码(靠窗,走道等
  44.         flag    number(1),      /* 标志:0正常,1占用,2已售,3暂不可用,-1禁售 */
  45.         used_dev varchar2(16) null, /* 最后操作终端 */
  46.         used_uid varchar2(16) null, /* 最后操作人 */
  47.         used_time date  null,           /* 最后操作时间 YYYY-MM-DD HH24:MI:SS */
  48.         primary key(start_date,beg_station,Train_no,Carno,
  49.                         seat_no,seat_type)
  50. );
  51. -- create index seat_idx on seat(beg_station,on_date,run_train,end_station);
  52. create index seat_release on seat(flag,used_time); /* 释放占用 */

  53. drop table seat_remant;
  54. create table seat_remant (      /* 存量表 */
  55.         on_date date,                   /* 上车日期 */
  56.         beg_station varchar2(4),        /* 上车站略码 */
  57.         run_train varchar2(12),         /* 运行车次 */
  58.         Carno number(2),        /* 车厢号,不分车厢的票车厢号=0 */
  59.         seat_type number(4),    /*席别,0=无号*/
  60.         purpose number(9),              /* 用途 */
  61.         end_station number(3),  /* 最远站 */
  62.         amoung  number(3),      /* 数量 */
  63.         primary key(on_date,beg_station,run_train,Carno,
  64.                 seat_type,purpose,end_station)
  65. );
  66. drop table station;
  67. create table station (
  68.         station_code varchar2(4),
  69.         station_name varchar2(20),
  70.         beg_date     date,
  71.         end_date     date,
  72.         abbreviation varchar2(6) null,
  73.         unit         varchar2(16) null,
  74.         line         varchar2(8) null,
  75.         area         varchar2(16) null,
  76.         spell        varchar2(20),
  77.         station_type varchar2(2) null,
  78.         statis_code  number(10) null,
  79.         flag         number(1),         /* 0:有效,其它无效 */
  80.         ac_fee     number(2),           /* 车站空调费 */
  81.         x            number(8,3) ,      /* 经度 */
  82.         y            number(8,3),       /* 纬度 */
  83.         primary key (station_code,end_date)
  84. );
  85. create index station_py on station(spell);
  86. create index station_name on station(station_name);

  87. drop table Train;
  88. create table Train (    /* 车次表 */
  89.         Train_no        varchar2(12),   /* 全车次 */
  90.         beg_date        date,           /* 有效起始日 */
  91.         end_date        date,           /* 有效截止日 */
  92.         start_station   varchar2(4),    /* 始发站  */
  93.         end_station     varchar2(4),    /* 终到站 */
  94.         station_num     number(3),      /* 停站数 */
  95.         total_distance  number(6),      /* 总里程 */
  96.         start_time      number(4),      /* 发车时间,分钟数 */
  97.         iterms          number(2),      /* 席位组数 */
  98.         cycle           varchar2(31),   /* 计算席位周期 */
  99.         gride           char(5),            /* 等级,普、快、特快等 */
  100.         price_mode      number(6),          /* 票价规则 */
  101.         discount_mode   number(6),          /* 折扣规则 */
  102.         days            number(3) null, /*  席位发行天数 */
  103.         flag            number(1),      /* 0可用,1不可用 */
  104.         owner           varchar2(16) null,  /* 担当单位 */
  105.         note            varchar2(50) null,              /* 备注  */
  106.         primary key (Train_no,end_date)
  107. );

  108. drop table stop_station;
  109. create table stop_station (
  110.         Train_no        varchar2(12),  /*  全车次 */
  111.         run_Train_no    varchar2(6),  /* 运行车次 */
  112.         sequence        number(3),              /* 顺号 */
  113.         beg_date        date,           /* 有效起始日期 */
  114.         end_date        date,           /* 有效结束日期 */
  115.         station_code    varchar2(4),    /* 车站代码 */
  116.         distance        number(6),              /* 自始发站里程 */
  117.         running_time    number(6),              /* 自始发站运行分钟数 */
  118.         stop_time       number(2),              /* 停靠分钟数 */
  119.         over            number(4) null, /* 超员数(本站可售无号数) */
  120.         flag            number(1),              /* 0可用,1封站 */
  121.         primary key  (Train_no,sequence,end_date )
  122. );
  123. create index s_station_q on stop_station (Train_no,station_code,end_date);
  124. create index stop_station_idx on stop_station(station_code,run_Train_no,end_date);


复制代码

[ 本帖最后由 yulihua49 于 2009-3-6 17:07 编辑 ]

使用道具 举报

回复
论坛徽章:
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
274#
 楼主| 发表于 2009-3-6 11:35 | 只看该作者
原帖由 yulihua49 于 2009-3-6 11:10 发表

stop_station(station_code,run_Train_no,end_date);



车站表station数据:
  1. BNHP|北京南|2008-02-01|2099-12-31||01010000|||bjn|KY|101001|0|1|0|0|
  2. YZHP|亦庄|2008-02-01|2099-12-31||01010000|||yz|KY|101002|0|1|0|0|
  3. YLHP|永乐|2008-02-01|2099-12-31||01010000|||lf|KY|101003|0|0|0|0|
  4. WQHP|武清|2008-02-01|2099-12-31||01010000|||wq|XC|101004|1|0|0|0|
  5. TJHP|天津|2008-02-01|2099-12-31||01010000|||tj|KY|101005|0|1|0|0|
  6. TSHP|唐山|2008-02-01|2099-12-31||01010000|||ts|KY|101006|0|0|0|0|
  7. QHHP|秦皇岛|2008-02-01|2099-12-31||01010000|||qhd|KY|101008|0|0|0|0|
  8. SJHP|石家庄|2008-02-01|2099-12-31||01010000|||sjz|KY|101009|0|1|0|0|
  9. BDHP|保定|2008-02-01|2099-12-31||01010000|||bd|KY|101010|0|0|0|0|
  10. BHHP|北戴河|2008-02-01|2099-12-31||01010000|||bdh|KY|101007|0|1|0|0|
复制代码


车次表train数据:

tuxticket@jgbticket:~/test> ./unldasc -f ld.ini train  
H1|2008-02-01|2099-12-31|BNHP|TJHP|6|130|495|1|1|G04 |0|0||0|01010000||
H2|2008-02-01|2099-12-31|TJHP|BNHP|6|130|570|1|1|G04 |0|0||0|01010000||
H4|2008-02-01|2008-03-31|SJHP|QHHP|7|590|1430|1|01|G04 |0|0||0|01010000||
H4A|2008-02-01|2008-03-31|SJHP|BHHP|6|540|1430|1|10|G04 |0|0||0|01010000||
H4|2008-04-01|2099-12-31|SJHP|QHHP|7|590|780|1|01|G04 |0|0|30|0|01010000||
H4A|2008-04-01|2099-12-31|SJHP|BHHP|6|540|780|1|10|G04 |0|0|30|0|01010000||
H6A|2008-04-03|2099-12-31|BHHP|SJHP|6|540|10|1|10|G04 |0|0|30|0|01010000|H6|
H6B|2008-04-01|2099-12-31|QHHP|SJHP|7|590|1435|1|10|G04 |0|0|30|0|01010000|H6|
停靠站表数据:
tuxticket@jgbticket:~/test> ./unldasc -f ld.ini stop_station
H1|H1|0|2008-02-01|2099-12-31|BNHP|0|0|0|0|0|
H1|H1|1|2008-02-01|2099-12-31|YZHP|30|10|2|30|0|
H1|H1|2|2008-02-01|2099-12-31|YLHP|60|20|2|30|0|
H1|H1|4|2008-02-01|2099-12-31|WQHP|90|31|2|0|0|
H1|H1|5|2008-02-01|2099-12-31|TJHP|130|45|0|0|0|
H2|H2|0|2008-02-01|2099-12-31|TJHP|0|0|0|0|0|
H2|H2|1|2008-02-01|2099-12-31|WQHP|40|14|2|0|0|
H2|H2|2|2008-02-01|2099-12-31|YLHP|70|25|2|30|0|
H2|H2|4|2008-02-01|2099-12-31|YZHP|100|35|2|30|0|
H2|H2|5|2008-02-01|2099-12-31|BNHP|130|45|0|0|0|
H4|H4|0|2008-02-01|2008-03-31|SJHP|0|0|0|0|0|
H4|H4|1|2008-02-01|2008-03-31|BDHP|150|30|2|0|0|
H4|H5|2|2008-02-01|2008-03-31|BNHP|270|57|5|0|0|
H4|H5|3|2008-02-01|2008-03-31|TJHP|400|88|3|40|0|
H4|H5|4|2008-02-01|2008-03-31|TSHP|470|106|1|40|0|
H4|H5|5|2008-02-01|2008-03-31|BHHP|540|122|5|40|0|
H4|H5|6|2008-02-01|2008-03-31|QHHP|590|137|0|0|0|
H4A|H4|0|2008-02-01|2008-03-31|SJHP|0|0|0|0|0|
H4A|H4|1|2008-02-01|2008-03-31|BDHP|150|30|2|0|0|
H4A|H5|2|2008-02-01|2008-03-31|BNHP|270|57|5|0|0|
H4A|H5|3|2008-02-01|2008-03-31|TJHP|400|88|3|40|0|
H4A|H5|4|2008-02-01|2008-03-31|TSHP|470|106|1|40|0|
H4A|H5|5|2008-02-01|2008-03-31|BHHP|540|122|0|0|0|
H6B|H6|0|2008-04-01|2099-12-31|QHHP|0|0|0|0|0|
H6B|H6|1|2008-04-01|2099-12-31|BHHP|50|10|5|0|0|
H6B|H6|2|2008-04-01|2099-12-31|TSHP|120|30|1|0|0|
H6B|H6|3|2008-04-01|2099-12-31|TJHP|190|46|3|0|0|
H6B|H3|4|2008-04-01|2099-12-31|BNHP|320|75|3|0|0|
H6B|H3|5|2008-04-01|2099-12-31|BDHP|440|103|1|40|0|
H6B|H3|6|2008-04-01|2099-12-31|SJHP|590|134|5|0|0|
H6A|H6|0|2008-04-01|2099-12-31|BHHP|0|0|0|0|0|
H6A|H6|1|2008-04-01|2099-12-31|TSHP|70|15|1|0|0|
H6A|H6|2|2008-04-01|2099-12-31|TJHP|140|31|3|0|0|
H6A|H3|3|2008-04-01|2099-12-31|BNHP|270|59|3|0|0|
H6A|H3|4|2008-04-01|2099-12-31|BDHP|390|87|1|40|0|
H6A|H3|5|2008-04-01|2099-12-31|SJHP|540|118|5|0|0|
H4|H4|0|2008-04-01|2099-12-31|SJHP|0|0|0|0|0|
H4|H4|1|2008-04-01|2099-12-31|BDHP|150|30|2|0|0|
H4|H5|2|2008-04-01|2099-12-31|BNHP|270|57|5|0|0|
H4|H5|3|2008-04-01|2099-12-31|TJHP|400|88|3|40|0|
H4|H5|4|2008-04-01|2099-12-31|TSHP|470|106|1|40|0|
H4|H5|5|2008-04-01|2099-12-31|BHHP|540|122|5|40|0|
H4|H5|6|2008-04-01|2099-12-31|QHHP|590|137|0|0|0|
H4A|H4|0|2008-04-01|2099-12-31|SJHP|0|0|0|0|0|
H4A|H4|1|2008-04-01|2099-12-31|BDHP|150|30|2|0|0|
H4A|H5|2|2008-04-01|2099-12-31|BNHP|270|57|5|0|0|
H4A|H5|3|2008-04-01|2099-12-31|TJHP|400|88|3|40|0|
H4A|H5|4|2008-04-01|2099-12-31|TSHP|470|106|1|40|0|
H4A|H5|5|2008-04-01|2099-12-31|BHHP|540|122|0|0|0|

tuxticket@jgbticket:~/test> ./unldasc -f ld.ini pre_seat_index
H1|1|2008-02-01|2099-12-31|0|2009-03-06 10:50:17||
H2|1|2008-02-01|2099-12-31|0|2009-03-06 10:50:18||
H4|1|2008-02-01|2008-03-31|0|||
H4A|1|2008-02-01|2008-03-31|0|||
H4|1|2008-04-01|2099-12-31|0|2009-03-06 10:49:46||
H4A|1|2008-04-01|2099-12-31|0|2009-03-06 10:50:18||
H6A|1|2008-04-01|2099-12-31|0|2009-03-06 10:50:18|H6|
H6B|1|2008-04-01|2099-12-31|0|2009-03-06 10:50:19|H6|

tuxticket@jgbticket:~/test> ./unldasc -f ld.ini pre_seat      
H1:1:20080201|1|12|1|120|0|5|0|0|G04|
H1:1:20080201|2|12|1|120|0|5|0|0|G04|
H1:1:20080201|3|12|1|120|0|1|0|0|G04|
H1:1:20080201|3|12|1|120|1|5|0|0|G04|
H1:1:20080201|4|12|1|120|0|2|0|0|G04|
H1:1:20080201|4|12|1|120|2|5|0|0|G04|
H1:1:20080201|5|13|1|50|0|5|0|0|G04|
H1:1:20080201|5|13|51|70|0|1|0|0|G04|
H1:1:20080201|5|13|51|70|1|5|0|0|G04|
H1:1:20080201|5|13|71|100|0|2|0|0|G04|
H1:1:20080201|5|13|71|100|2|5|0|0|G04|
H2:1:20080201|1|12|1|120|0|5|0|0|G04|
H2:1:20080201|2|12|1|120|0|5|0|0|G04|
H2:1:20080201|3|12|1|120|0|1|0|0|G04|
H2:1:20080201|3|12|1|120|1|5|0|0|G04|
H2:1:20080201|4|12|1|120|0|2|0|0|G04|
H2:1:20080201|4|12|1|120|2|5|0|0|G04|
H2:1:20080201|5|13|1|50|0|5|0|0|G04|
H2:1:20080201|5|13|51|70|0|1|0|0|G04|
H2:1:20080201|5|13|51|70|1|5|0|0|G04|
H2:1:20080201|5|13|71|100|0|2|0|0|G04|
H2:1:20080201|5|13|71|100|2|5|0|0|G04|
H4:1:20080201|1|12|1|120|0|6|0|0|G04|
H4:1:20080201|2|12|1|120|0|2|0|0|G04|
H4:1:20080201|2|12|1|120|2|6|0|0|G04|
H4:1:20080201|3|12|1|120|0|3|0|0|G04|
H4:1:20080201|3|12|1|120|3|6|0|0|G04|
H4:1:20080201|4|12|1|120|0|1|0|0|G04|
H4:1:20080201|4|12|1|120|1|6|0|0|G04|
H4:1:20080201|5|20|1|20|0|6|0|0|G04|
H4:1:20080201|5|20|21|22|0|1|0|0|G04|
H4:1:20080201|5|20|21|22|1|6|0|0|G04|
H4:1:20080201|6|13|1|20|0|6|0|0|G04|
H4:1:20080201|6|13|21|30|0|1|0|0|G04|
H4:1:20080201|6|13|21|30|1|6|0|0|G04|
H4:1:20080201|6|13|31|60|0|2|0|0|G04|
H4:1:20080201|6|13|31|60|2|6|0|0|G04|
H4:1:20080201|6|13|61|80|0|3|0|0|G04|
H4:1:20080201|6|13|61|80|3|6|0|0|G04|
H4:1:20080201|6|13|81|100|0|6|0|0|G04|
H4A:1:20080201|1|12|1|120|0|5|0|0|G04|
H4A:1:20080201|2|12|1|120|0|2|0|0|G04|
H4A:1:20080201|2|12|1|120|2|5|0|0|G04|
H4A:1:20080201|3|12|1|120|0|3|0|0|G04|
H4A:1:20080201|3|12|1|120|3|5|0|0|G04|
H4A:1:20080201|4|12|1|120|0|1|0|0|G04|
H4A:1:20080201|4|12|1|120|1|5|0|0|G04|
H4A:1:20080201|5|20|1|20|0|5|0|0|G04|
H4A:1:20080201|5|20|21|22|0|1|0|0|G04|
H4A:1:20080201|5|20|21|22|1|5|0|0|G04|
H4A:1:20080201|6|13|1|20|0|5|0|0|G04|
H4A:1:20080201|6|13|21|30|0|1|0|0|G04|
H4A:1:20080201|6|13|21|30|1|5|0|0|G04|
H4A:1:20080201|6|13|31|60|0|2|0|0|G04|
H4A:1:20080201|6|13|31|60|2|5|0|0|G04|
H4A:1:20080201|6|13|61|80|0|3|0|0|G04|
H4A:1:20080201|6|13|81|100|0|5|0|0|G04|
H4A:1:20080201|6|13|61|80|3|5|0|0|G04|
H6A:1:20080401|1|12|1|120|0|5|0|0|G04|
H6A:1:20080401|2|12|1|120|0|1|0|0|G04|
H6A:1:20080401|2|12|1|120|1|5|0|0|G04|
H6A:1:20080401|3|12|1|120|0|2|0|0|G04|
H6A:1:20080401|3|12|1|120|2|5|0|0|G04|
H6A:1:20080401|4|12|1|120|0|5|0|0|G04|
H6A:1:20080401|5|20|1|20|0|5|0|0|G04|
H6A:1:20080401|5|20|21|22|0|2|0|0|G04|
H6A:1:20080401|5|20|21|22|2|5|0|0|G04|
H6A:1:20080401|6|13|1|50|0|5|0|0|G04|
H6A:1:20080401|6|13|51|60|0|1|0|0|G04|
H6A:1:20080401|6|13|51|60|1|5|0|0|G04|
H6A:1:20080401|6|13|61|80|0|2|0|0|G04|
H6A:1:20080401|6|13|61|80|2|5|0|0|G04|
H6A:1:20080401|6|13|81|100|0|3|0|0|G04|
H6A:1:20080401|6|13|81|100|3|5|0|0|G04|
H6B:1:20080401|1|12|1|120|0|6|0|0|G04|
H6B:1:20080401|2|12|1|120|0|2|0|0|G04|
H6B:1:20080401|2|12|1|120|2|6|0|0|G04|
H6B:1:20080401|3|12|1|120|0|3|0|0|G04|
H6B:1:20080401|3|12|1|120|3|6|0|0|G04|
H6B:1:20080401|4|12|1|120|0|1|0|0|G04|
H6B:1:20080401|4|12|1|120|1|6|0|0|G04|
H6B:1:20080401|5|20|1|10|0|6|0|0|G04|
H6B:1:20080401|5|20|11|20|0|1|0|0|G04|
H6B:1:20080401|5|20|11|20|1|6|0|0|G04|
H6B:1:20080401|5|20|21|22|0|3|0|0|G04|
H6B:1:20080401|5|20|21|22|3|6|0|0|G04|
H6B:1:20080401|6|13|1|20|0|6|0|0|G04|
H6B:1:20080401|6|13|21|50|0|1|0|0|G04|
H6B:1:20080401|6|13|21|50|1|6|0|0|G04|
H6B:1:20080401|6|13|51|60|0|2|0|0|G04|
H6B:1:20080401|6|13|51|60|2|6|0|0|G04|
H6B:1:20080401|6|13|61|80|0|3|0|0|G04|
H6B:1:20080401|6|13|61|80|3|6|0|0|G04|
H6B:1:20080401|6|13|81|100|0|4|0|0|G04|
H6B:1:20080401|6|13|81|100|4|6|0|0|G04|
H4A:1:20080401|1|12|1|120|0|5|0|0|G04|
H4A:1:20080401|2|12|1|120|0|2|0|0|G04|
H4A:1:20080401|2|12|1|120|2|5|0|0|G04|
H4A:1:20080401|3|12|1|120|0|3|0|0|G04|
H4A:1:20080401|3|12|1|120|3|5|0|0|G04|
H4A:1:20080401|4|12|1|120|0|1|0|0|G04|
H4A:1:20080401|4|12|1|120|1|5|0|0|G04|
H4A:1:20080401|5|20|1|20|0|5|0|0|G04|
H4A:1:20080401|5|20|21|22|0|1|0|0|G04|
H4A:1:20080401|5|20|21|22|1|5|0|0|G04|
H4A:1:20080401|6|13|1|20|0|5|0|0|G04|
H4A:1:20080401|6|13|21|30|0|1|0|0|G04|
H4A:1:20080401|6|13|21|30|1|5|0|0|G04|
H4A:1:20080401|6|13|31|60|0|2|0|0|G04|
H4A:1:20080401|6|13|31|60|2|5|0|0|G04|
H4A:1:20080401|6|13|61|80|0|3|0|0|G04|
H4A:1:20080401|6|13|61|80|3|5|0|0|G04|
H4A:1:20080401|6|13|81|100|0|5|0|0|G04|
H4:1:20080401|1|12|1|120|0|6|0|0|G04|
H4:1:20080401|2|12|1|120|0|2|0|0|G04|
H4:1:20080401|2|12|1|120|2|6|0|0|G04|
H4:1:20080401|3|12|1|120|0|3|0|0|G04|
H4:1:20080401|3|12|1|120|3|6|0|0|G04|
H4:1:20080401|4|12|1|120|0|1|0|0|G04|
H4:1:20080401|4|12|1|120|1|6|0|0|G04|
H4:1:20080401|5|20|1|20|0|6|0|0|G04|
H4:1:20080401|5|20|21|22|0|1|0|0|G04|
H4:1:20080401|5|20|21|22|1|6|0|0|G04|
H4:1:20080401|6|13|1|20|0|6|0|0|G04|
H4:1:20080401|6|13|21|30|0|1|0|0|G04|
H4:1:20080401|6|13|21|30|1|6|0|0|G04|
H4:1:20080401|6|13|31|60|0|2|0|0|G04|
H4:1:20080401|6|13|31|60|2|6|0|0|G04|
H4:1:20080401|6|13|61|80|0|3|0|0|G04|
H4:1:20080401|6|13|81|100|0|6|0|0|G04|
H4:1:20080401|6|13|61|80|3|6|0|0|G04|


[/code]

看到我使用万能卸载程序了吗?没有包装器,这东西挺难写的。

[ 本帖最后由 yulihua49 于 2009-3-6 17:08 编辑 ]

使用道具 举报

回复
论坛徽章:
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
275#
 楼主| 发表于 2009-3-6 13:44 | 只看该作者
原帖由 nyfor 于 2009-3-5 14:02 发表
据 Oracle 文档介绍, Pro*C 使用的并非是 OCI (也许最终使用的是 OCI 吧), 它使用的是依赖于 Oracle 版本的 SQLLIB 库, 当然 Pro*C 中也可以直接调用 OCI.  

非常佩服本帖中两位的针锋讨论.

楼主在这个版块发这样的帖子, 引来的必定是一片的质疑声(包括我).

我觉得楼主不应该强调你的包装器的性能, 或许你应该强调的是使用你的包装器带来的开发效率(当然对于不太了解Oracle,不太了解SQL的程序员来说).

通看整片帖子的过程中, 我曾想起过以下词句(只当做调侃,别无它意): 龙芯一号, 汉语编程, 方舟子.

诚然, 对于楼主的包装器它固然也有它的优点(那些优点对于精于Oracle数据库编程的人员来说可能完全是缺点).

把这贴再顶起来, 另外建议 newkid 以本为内容发布一新帖, 不给你加一个精华, 实在是.....

哪就再show一个程序吧,就是上边的万能卸载,一会功夫就写完了,调试也很简单:
要是你写这么个东西,要多少时间,开发效率应该明白了吧?

  1. int unloadfile(T_SQL_Connect *SQL_Connect,char *tablename,FILE *ifd,FILE *ofd,int Pflg,char *where,int buflen)
  2. {
  3. char *p;
  4. DAU _DAU;
  5. int rows,ret,upd,loss,num=0,cur;

  6.         ShowLog(5,"unloadfile:entry");
  7.         ret=DAU_init(&_DAU,SQL_Connect,tablename,0,0);
  8.         if(ret) {
  9.                 ShowLog(1,"unloadfile:DAU_init tabname=%s,ret=%d",tablename,ret);
  10.                 return -1;
  11.         }
  12.         ret=DAU_prepare(&_DAU,where);
  13.         ShowLog(5,"unloadfile:prepare=%d,%s",ret,where);
  14.         if(ret) {
  15.                 ShowLog(1,"unloadfile:err=%d,%s",ret,where);
  16.                 return ret;
  17.         }
  18.         cur=_DAU.cursor;
  19.         ret=1;
  20.         while(p=___SQL_Fetch(SQL_Connect,cur,&ret)) {
  21. //              JSON_OBJECT json=json_object_new_object();
  22. //              net_dispack(_DAU.srm.rec,p,_DAU.srm.tp);
  23. //              net_pack(where,_DAU.srm.rec,_DAU.srm.tp);
  24.                 fprintf(ofd,"%s\n",p);
  25.                 free(p);
  26. //              DAU_toJSON(&_DAU,json,0);
  27. //              p=json_object_to_json_string(json);
  28. //              fprintf(ofd,"%s\n",p);
  29. //              json_object_put(json);
  30.                 num++;
  31.         }
  32.         DAU_free(&_DAU);
  33.         ShowLog(2,"unload %s:rows=%d",tablename,num);
  34.         return 0;
  35. }
复制代码


性能嘛,卸载128万的seat,23秒。
用途嘛,反正你们只玩O记的。
我们?
可以:

unldasc -f ld.ini tabname | rsh host -l user ldasc.sh tabname

一个数据表从一个主机转移到另一个主机,不用写别的程序了。

[ 本帖最后由 yulihua49 于 2009-3-6 13:48 编辑 ]

使用道具 举报

回复
论坛徽章:
7
2010数据库技术大会纪念徽章
日期:2010-05-13 09:34:22
276#
发表于 2009-3-6 15:24 | 只看该作者
每天看下这个帖子都变成我的习惯了,呵呵

btw:newkid能否给出一个数据库使用效率高,而程序员又便于开发的解决方案么?
我近期也在思考快速开发问题呢

使用道具 举报

回复
论坛徽章:
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
277#
 楼主| 发表于 2009-3-6 17:15 | 只看该作者
原帖由 cuicg 于 2009-3-6 15:24 发表
每天看下这个帖子都变成我的习惯了,呵呵

btw:newkid能否给出一个数据库使用效率高,而程序员又便于开发的解决方案么?
我近期也在思考快速开发问题呢

快速开发,简单一点,就是不写列名。一种思路是界面工具查询数据结构,自动生成列名,然后人工修改。JAVA框架这么做的比较多。
但是遇到像万能加载、卸载这种情况,(我们在三层C/S模型下,向客户端提供通用的增、删、改、查服务,也是这种情况)写程序时不知道表名,这个办法不灵。
还有就是数据结果落地的问题,落在离散变量,肯定不可能通用,JAVA是落在对象,就是所谓ORM,C就只能落在struct里了,就是我这里的SRM。
那些复杂的SQL,绝对是智慧的结晶,任何自动化系统都不可能有这个智慧。所以,自动系统以包装器形式提供是比较可取的,急了就赤膊上阵,脱了包装直接干。
我上边的万能卸载就脱了,直接用___SQL_Fetch().也让大家看到了DAU部分内部结构。如果有个肯定的需求,其内部结构和处理方法可以公开。
如果以引擎形式提供,绕不开,躲不过就比较麻烦。

这个帖子,我想是抛砖引玉,大家在快速开发上动些脑筋,程序程序生成器?引擎?包装?都可以有自己的办法,大家切磋一下,互相借鉴。就怕扔了石头没响。

[ 本帖最后由 yulihua49 于 2009-3-6 17:38 编辑 ]

使用道具 举报

回复
论坛徽章:
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
278#
发表于 2009-3-7 03:03 | 只看该作者

先说说我对你程序的解读,你看有没有错:

车次的选取:
根据传入的车次参数(如果参数有值的话),此外必须满足 flag=0 AND end_date >= today
根据公式计算jobday, jobday必须在车次表的 beg_date AND end_date之间;
车次表算出的jobday对应的周期值ITEM不能为0;

停靠站的选取:
根据车次表的jobday和车次读取停靠站, 限制条件还有flag=0.
生成无号席位时还有station_num-1 > sequence,普通席位则加上母表的BEG_STATION作为条件。

无号席位:
根据停靠站的1~over为座号生成席位。

有号席位:
根据车次表的车次,jobday对应的周期值ITEM,读取pre_seat_index, 限制条件还有flag=0 AND jobday BETWEEN beg_date AND end_date
根据车号:ITEM:BEG_DATE拼出来的一个ID读取母表pre_seat;
根据母表的beg_seatno AND end_seatno生成席位,(如果硬卧生成三条记录),如果卧铺修正SEAT_TYPE.

以下是我的方法:

先建立一个参数表:
CREATE GLOBAL TEMPORARY TABLE seat_parameter (    -- 参数表
          dflg           NUMBER(1)    -- 控制JOBDAY的计算
         ,start_date     DATE         -- today
         ,end_date       DATE         -- 如果非空,则可以生成多天的数据
         ,train_no       VARCHAR2(12) -- 如果为0或NULL则忽略
          ) ON COMMIT DELETE ROWS
/

把两个复杂查询抽出来建立视图:
CREATE OR REPLACE VIEW vw_train
AS  ------ 无号和普通都用到的一些变换计算和公共子查询(车次和停靠站的选取)
SELECT t.train_no
      ,t.gride  
      ,t.station_num
      ,t.jobday
      ,t.item
      ,cz.station_code                                           AS beg_station
      ,t.jobday+(t.start_time+cz.running_time+cz.stop_time)/1440 AS on_date
      ,cz.run_train_no                                           AS run_train
      ,cz.over
      ,cz.sequence
  FROM (SELECT t2.*
              ,SUBSTR(cycle,MOD(jobday-beg_date, cycle)+1,1)   AS item -- beg_date既表示该车次的有效起始日期,又表示周期的起始点。cycle字段表达一个周期,如 1020,表示第一天开1组,第二天不开,第三天开2组,第4天不开。以后周而复始。
         FROM (SELECT train.*
                     ,(CASE WHEN NVL(p.dflg,0)=0 THEN p.today + (CASE WHEN train.days>0 THEN train.days ELSE 10 END)
                            ELSE today
                       END) AS jobday     --- 如果dflg为空则从train表中取得
               FROM train
                   ,(SELECT dflg   -- 根据end_date,start_date算出一个today的集合。如果相等或end_date为空则只有一行
                           ,start_date + ROWNUM -1 AS today
                           ,train_no
                       FROM seat_parameter
                     CONNECT BY ROWNUM <= NVL(end_date,start_date) - start_date +1
                     ) p     
               WHERE train.flag=0 AND train.end_date >= p.today
                     AND (train.train_no=p.train_no OR NVL(p.train_no,'0')='0')
              ) t2
        ) t
      ,stop_station cz
WHERE t.jobday BETWEEN t.beg_date AND t.end_date
       AND t.item<>'0'
       AND cz.train_no=t.train_no
       AND t.jobday BETWEEN cz.beg_date AND cz.end_date
       AND cz.flag=0
/


CREATE OR REPLACE VIEW vw_seat
AS    --- 利用上述视图vw_train和附加逻辑生成席位
WITH tr AS (SELECT * FROM vw_train)
    ,vw_seat_no AS (SELECT ROWNUM as seat_no FROM DUAL CONNECT BY ROWNUM<=999)
SELECT -- 第一部分:发布无号席位
       tr.train_no          AS train_no         
      ,tr.gride             AS gride  
      ,tr.station_num-1     AS end_station      
      ,tr.jobday            AS start_date                                
      ,0                    AS carno                                    
      ,0                    AS purpose                                   
      ,0                    AS seat_type                                 
      ,0                    AS shortest_station                          
      ,0                    AS flag                                      
      ,tr.beg_station       AS beg_station      
      ,tr.on_date           AS on_date      
      ,tr.run_train         AS run_train   
      ,0                    AS pro         
      ,vw_seat_no.seat_no   AS seat_no      
FROM  tr
     ,vw_seat_no
WHERE tr.station_num-1 > tr.sequence        
      AND tr.over >= vw_seat_no.seat_no     
UNION ALL -- 第二部分:发布普通席位
SELECT tr.train_no          AS train_no              
      ,ps.gride             AS gride                 
      ,ps.end_station       AS end_station           
      ,tr.jobday            AS start_date            
      ,ps.carno             AS carno                       
      ,ps.purpose           AS purpose               
      ,(CASE WHEN ps.seat_type = 20 THEN 20+vw_seat_type_adj.rn         -- 硬卧是一席3号,下中上。seat_type:20=硬卧,21硬卧下,22硬卧中,23硬卧上
             WHEN ps.seat_type = 30 THEN 31+MOD(vw_seat_no.seat_no+1,2) -- 软卧是一席一号单下双上: 30软卧,31软卧下,32软卧上。
             ELSE ps.seat_type
        END)                AS seat_type            
      ,ps.shortest_station  AS shortest_station      
      ,0                    AS flag                                    
      ,tr.beg_station       AS beg_station           
      ,tr.on_date           AS on_date               
      ,tr.run_train         AS run_train            
      ,0                    AS pro                  
      ,vw_seat_no.seat_no   AS seat_no               
  FROM tr
      ,pre_seat ps
      ,pre_seat_index psi
      ,vw_seat_no
      ,(SELECT ROWNUM AS rn FROM DUAL CONNECT BY ROWNUM<=3) vw_seat_type_adj
WHERE psi.train_no=tr.train_no AND psi.item=tr.item AND tr.jobday BETWEEN psi.beg_date AND psi.end_date AND psi.flag=0
       AND ps.pre_id = tr.train_no||':'||tr.item||':'||TO_CHAR(psi.beg_date,'YYYYMMDD')
       AND tr.sequence = ps.beg_station   -- 和无号不同
       AND vw_seat_no.seat_no BETWEEN ps.beg_seatno AND ps.end_seatno
       AND (ps.seat_type=20       --- 硬卧,连接三行
            OR ps.seat_type <>20 AND vw_seat_type_adj.rn = 1   -- 非硬卧,只连接一行
           )
/

CREATE OR REPLACE VIEW vw_new_seat
AS
SELECT * FROM vw_seat v
WHERE NOT EXISTS (SELECT 1 FROM seat s
                    WHERE s.start_date  = v.start_date  
                          AND s.beg_station = v.beg_station
                          AND s.Train_no    = v.Train_no   
                          AND s.Carno       = v.Carno      
                          AND s.seat_no     = v.seat_no     
                          AND s.seat_type   = v.seat_type   
                  )
/

建立存储过程生成席位:
CREATE OR REPLACE PROCEDURE make_seats (
          p_train_no     IN VARCHAR2 DEFAULT NULL
         ,p_dflg         IN NUMBER    DEFAULT 0    ---- 如果1则不用TRAINS里面的偏移量      
         ,p_offset_days  IN NUMBER    DEFAULT 0    ---- 缺省当天则偏移为0, +1为第二天
         ,p_created_days IN NUMBER    DEFAULT 1    ---- 缺省一天
         )
AS
   lv_timestamp DATE := SYSDATE;
BEGIN
   INSERT INTO seat_parameter (    -- 参数表
          dflg            -- 控制JOBDAY的计算
         ,start_date      -- today
         ,end_date        -- 如果非空,则可以生成多天的数据
         ,train_no        -- 如果为0或NULL则忽略
          )
   VALUES(p_dflg        
         ,TRUNC(SYSDATE)+p_offset_days  
         ,TRUNC(SYSDATE)+p_offset_days + p_created_days -1
         ,p_train_no   
         );

   MERGE INTO seat_remant s
   USING (SELECT on_date                -- 上车日期
                ,beg_station            -- 上车站略码
                ,run_train              -- 运行车次
                ,Carno                  -- 车厢号,不分车厢的票车厢号=0
                ,seat_type              -- 席别,0=无号
                ,purpose                -- 用途
                ,end_station            -- 最远站
                ,COUNT(*)  AS amoung              -- 数量
            FROM vw_new_seat
           GROUP BY on_date                -- 上车日期
                ,beg_station            -- 上车站略码
                ,run_train              -- 运行车次
                ,Carno                  -- 车厢号,不分车厢的票车厢号=0
                ,seat_type              -- 席别,0=无号
                ,purpose                -- 用途
                ,end_station            -- 最远站
         ) n
   ON (s.on_date       = n.on_date                -- 上车日期
       AND s.beg_station   = n.beg_station            -- 上车站略码
       AND s.run_train     = n.run_train              -- 运行车次
       AND s.Carno         = n.Carno                  -- 车厢号,不分车厢的票车厢号=0
       AND s.seat_type     = n.seat_type              -- 席别,0=无号
       AND s.purpose       = n.purpose                -- 用途
       AND s.end_station   = n.end_station            -- 最远站
       )
   WHEN MATCHED THEN UPDATE SET s.amoung = s.amoung+n.amoung
   WHEN NOT MATCHED THEN INSERT (on_date                -- 上车日期
                                ,beg_station            -- 上车站略码
                                ,run_train              -- 运行车次
                                ,Carno                  -- 车厢号,不分车厢的票车厢号=0
                                ,seat_type              -- 席别,0=无号
                                ,purpose                -- 用途
                                ,end_station            -- 最远站
                                ,amoung
                                )
                         VALUES (n.on_date                -- 上车日期
                                ,n.beg_station            -- 上车站略码
                                ,n.run_train              -- 运行车次
                                ,n.Carno                  -- 车厢号,不分车厢的票车厢号=0
                                ,n.seat_type              -- 席别,0=无号
                                ,n.purpose                -- 用途
                                ,n.end_station            -- 最远站
                                ,n.amoung
                                );

   INSERT INTO seat (
          train_no               
         ,gride            -- grade?      
         ,end_station            
         ,start_date            
         ,carno                  
         ,purpose               
         ,seat_type              
         ,shortest_station      
         ,flag                  
         ,beg_station            
         ,on_date               
         ,run_train              
         ,pro                    
         ,seat_no               
         ,used_time              
         ,used_dev               
         ,used_uid               
         )
   SELECT train_no               
         ,gride            
         ,end_station            
         ,start_date            
         ,carno                  
         ,purpose               
         ,seat_type              
         ,shortest_station      
         ,flag                  
         ,beg_station            
         ,on_date               
         ,run_train              
         ,pro                    
         ,seat_no               
         ,lv_timestamp AS used_time              
         ,'xwfb' AS used_dev               
         ,'xwfb' AS used_uid               
     FROM vw_new_seat;

         
   MERGE INTO pre_seat_index psi
   USING (SELECT DISTINCT psi.ROWID rid
            FROM pre_seat_index psi
                ,vw_train tr
           WHERE psi.train_no=tr.train_no AND psi.item=tr.item AND tr.jobday BETWEEN psi.beg_date AND psi.end_date AND psi.flag=0
         ) n
   ON (n.rid = psi.ROWID)
   WHEN MATCHED THEN UPDATE
        SET psi.distribute_time = lv_timestamp;

   COMMIT;

END make_seats;
/


测试:
生成当天数据: (1860行,在0.7-0.9秒之间)
EXEC make_seats;

生成4天数据: (10736行, 大约用了1.7秒)
EXEC make_seats(NULL,0,0,4);

生成30天的数据是5.5秒。数据量越大越体现出SQL的优势。

里面有个查询用了两遍(因为要生成余额),改天我用临时表,看看会不会更快。

你说你3月5号一天生成5156行,导出DMP来看看?我找了半天不知道问题在哪里,有比较就好办多了。你可以运行一下我的程序,把数据拷到另一张表,再用你的结果作一下MINUS. 你只要告诉我一条无号、有号的遗漏数据,我就可以找出问题在哪里。如果能告诉我漏掉的是哪个母表记录就更好。



[ 本帖最后由 newkid 于 2009-3-7 07:52 编辑 ]

使用道具 举报

回复
论坛徽章:
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
279#
发表于 2009-3-7 03:44 | 只看该作者
原帖由 yulihua49 于 2009-3-6 13:44 发表

哪就再show一个程序吧,就是上边的万能卸载,一会功夫就写完了,调试也很简单:
要是你写这么个东西,要多少时间,开发效率应该明白了吧?


我写下面这个东西也就几分钟,但必须承认查SQLPLUS手册花了十几分钟:(把以下保存为unload.sql)

SET TERM OFF
SET HEADING OFF
SET VERIFY OFF
SET ECHO OFF
SET FEEDBACK OFF
SET PAGESIZE 0
SET LINESIZE 4000
SET TRIMS ON

SPOOL NEW.SQL

PROMPT SET HEADING OFF
PROMPT SET VERIFY OFF
PROMPT SET ECHO OFF
PROMPT SET FEEDBACK OFF
PROMPT SET PAGESIZE 0
PROMPT SET LINESIZE 4000
PROMPT SET TERM OFF
PROMPT SET TRIMS ON
PROMPT SPOOL OUTPUT.TXT
PROMPT ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD';;

SELECT 'SELECT '
       ||REPLACE(wmsys.wm_concat(COLUMN_NAME),',','||''|''||')
       ||' FROM &1;'
  FROM (SELECT * FROM USER_TAB_COLUMNS WHERE TABLE_NAME = '&1' ORDER BY COLUMN_ID);
  
PROMPT SPOOL OFF
PROMPT QUIT

SPOOL OFF

@@NEW.SQL

EXIT

用法:
SQLPLUS USER/PASSWORD@HOST @unload.sql TRAIN

在OUTPUT.TXT可以看到TRAIN的数据:
H1|2008-02-01|2099-12-31|BNHP|TJHP|6|130|495|1|1|G04  |0|0||0|01010000|
H2|2008-02-01|2099-12-31|TJHP|BNHP|6|130|570|1|1|G04  |0|0||0|01010000|
H4|2008-02-01|2008-03-31|SJHP|QHHP|7|590|1430|1|01|G04  |0|0||0|01010000|
H4A|2008-02-01|2008-03-31|SJHP|BHHP|6|540|1430|1|10|G04  |0|0||0|01010000|
H4|2008-04-01|2099-12-31|SJHP|QHHP|7|590|780|1|01|G04  |0|0|30|0|01010000|
H4A|2008-04-01|2099-12-31|SJHP|BHHP|6|540|780|1|10|G04  |0|0|30|0|01010000|
H6A|2008-04-03|2099-12-31|BHHP|SJHP|6|540|10|1|10|G04  |0|0|30|0|01010000|H6
H6B|2008-04-01|2099-12-31|QHHP|SJHP|7|590|1435|1|10|G04  |0|0|30|0|01010000|H6


一个数据表从一个主机转移到另一个主机,不用写别的程序了。


干吗要写程序?我们有exp,imp,expdp,impdp, 甚至sqlplus的COPY命令,功能和你这个东西完全不是一个等级的。

使用道具 举报

回复
论坛徽章:
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
280#
发表于 2009-3-7 04:28 | 只看该作者
原帖由 yulihua49 于 2009-3-6 17:15 发表

快速开发,简单一点,就是不写列名。一种思路是界面工具查询数据结构,自动生成列名,然后人工修改。JAVA框架这么做的比较多。
但是遇到像万能加载、卸载这种情况,(我们在三层C/S模型下,向客户端提供通用的增、删、改、查服务,也是这种情况)写程序时不知道表名,这个办法不灵。
还有就是数据结果落地的问题,落在离散变量,肯定不可能通用,JAVA是落在对象,就是所谓ORM,C就只能落在struct里了,就是我这里的SRM。
那些复杂的SQL,绝对是智慧的结晶,任何自动化系统都不可能有这个智慧。所以,自动系统以包装器形式提供是比较可取的,急了就赤膊上阵,脱了包装直接干。
我上边的万能卸载就脱了,直接用___SQL_Fetch().也让大家看到了DAU部分内部结构。如果有个肯定的需求,其内部结构和处理方法可以公开。
如果以引擎形式提供,绕不开,躲不过就比较麻烦。

这个帖子,我想是抛砖引玉,大家在快速开发上动些脑筋,程序程序生成器?引擎?包装?都可以有自己的办法,大家切磋一下,互相借鉴。就怕扔了石头没响。


我坚决反对隐藏列名。
工具只是帮你选取列名而已;我更爱用一个文本编辑器COPY&PASTE, 从来也不觉得选取列名有什么问题。我花的时间都在理解需求,至于写程序,对我来说就是个体力劳动,动脑筋的时候很少。

像楼主这样的程序:
DAU_copy(&remant_DAU,&seat_DAU,0);
看似很巧妙,其实就是一个隐患。你无法控制什么列需要复制。

楼主的DAU数据获取,从代码的字面上完全看不出因果关系。他用一个看似独立,但却和dau内部的srm.rec挂钩的stu来保存查询条件以及查询结果。

比方说这个模块:
int get_stop_station(DAU *DP,char *stmt)
{
char *p;
        p=DAU_mk_where(DP,"train_no,sequence",stmt);
        sprintf(p," AND beg_date <= :beg_date AND end_date >= :beg_date AND flag=0"
        if(0 >= DAU_select(DP,stmt,1)) {
                ShowLog(1,"get_stop_station stmt=%s",stmt);
                return DP->SQL_Connect->Errno;
        }
        return DAU_next(DP);
}

他为了查询一条数据必须这么做:
stop_station.sequence=pre_seat.beg_station;
stop_station.beg_date=jobday;
if(get_stop_station(&cz_DAU,stmt)) continue;

而在遥远的其他地方,还有给train_no赋值的代码!strcpy(stop_station.train_no,pre_index->train_no);
你看得出stop_station和cz_DAU是有联系的吗?看得出为了查询一个数据要这么多窍门吗?
明明白白的编程方法:get_stop_station就应该有train_no,sequence,beg_date作为输入参数。根据这些参数查询数据库数据。

而用同一个stop_station来保存查询参数(输入)和查询结果(输出),这也是混乱的地方。(看看你的adj_remant代码,有多少人能看出这是把一个数叠加到表原来的值上去?一般人会理解为翻番)这迟早都要出问题,而且出了问题很难追查。

这个生成票据的程序,是大循环套小循环,生成数据(seat的各个列)的代码是七零八落。和我的SQL的SELECT相比,哪个更清楚? 是你的C代码复杂还是SQL复杂?

再说说“数据结果落地”,我是尽量的少让它“落地”,实在要用游标的话,游标数据来源都集中在一个SELECT中,非常直观易懂;引用游标的列和C的结构用法是完全一样的。

关于代码生成器这类东西:首先你的代码必须具有一种机械的套路,生成器只是省得你打字而已。这主要发生在UI编程,后台处理是很少有的。我如果碰到这种需求就自己写一个。

包装器:如楼主所展示,包装器的代码更加隐晦,隐藏了一些在我看来最重要的信息,所以我不喜欢。

引擎:我不理解这个词在这里的意思。

[ 本帖最后由 newkid 于 2009-3-7 07:48 编辑 ]

使用道具 举报

回复

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

本版积分规则 发表回复

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