楼主: yulihua49

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

[复制链接]
论坛徽章:
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
81#
 楼主| 发表于 2008-12-9 09:29 | 只看该作者
建立新口令:??为什么在这里会建立新口令?

这是我们的一种认证形态,dev也是这样的,你可以看到。
初态是空的,第一次登陆承认任何口令,并登记。以后必须口令符合。这虽然有一个安全漏洞,但简化了安全管理。口令是不可逆的,如果遗忘口令,没有任何人能知道,只有删除,再登录一次。从删除到再登录就是一个不安全窗口。

那个程序不要求你写,只要你知道我想干嘛就行。那些DAO如果用存储过程,仍然要提取到appserver,一点没节约,还给SRM带来很大困难。
认证还没有决定是否数字签名,如果签名,那个计算量是不得了的,让数据库引擎做太不划算了。
数据库引擎掌控着昂贵的盘阵,完整、准确、及时的提供存取服务才是正道,他在那忙于计算,耽误了别人的存取请求恐怕不划算。

使用道具 举报

回复
论坛徽章:
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
82#
 楼主| 发表于 2008-12-9 09:33 | 只看该作者
原帖由 newkid 于 2008-12-9 00:19 发表


13年前我还在用486作做DOS下的FOXPRO呢,也没听说1000条数据的计算要花40分钟啊?肯定是哪里搞错了。

我举这个例子只是为了表明树的遍历不但不是ORACLE的劣势,反而是优势。试想自己你写代码来实现树的遍历要多少代码?哪怕是C程序,效率也比不上SQL。

一个窗口一班的量。总量好几百万的记录呢!当时索引没弄好。当时在一个台式机临时投产。后来换小型机就不这么差了。

使用道具 举报

回复
论坛徽章:
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
83#
发表于 2008-12-9 09:52 | 只看该作者
原帖由 yulihua49 于 2008-12-9 09:14 发表

我就知道这有诟病,但这只是一个极端情况的处理,用while好像更难懂,可以改。
free目前没好办法,JAVA的那种自动回收存在不确定性,再说C也没有提供。

堵车的程序就是2页15楼,你看那个循环没有完,后边应该是占用成功的席位(一行的全部内容)打包加入一个数组。最后返回这个数组。
我不希望你用一个表,然后返我游标,这样一是增加了IO,二是增加了堵车的机会。我的条件里是多选了几条记录,原来是多一倍,只占用请求的数量。可能想选择互相邻近的席位,或靠窗的,吸烟不吸烟的什么的,还没有想好算法,总之会有一些选择余地。这仍然是个DEMO,并非真正的程序。


你那个GOTO就是不断重试,WHILE也是不断重试,WHILE更直观易懂。

"我不希望你用一个表,然后返我游标,这样一是增加了IO,二是增加了堵车的机会"
你的思维还停留在SYBASE吧?你现在这样做也访问表,也逐条上锁,怎么我用存储过程来实现就增加了IO和堵车机会?等我写出来你倒是证明“堵车”给我看。
选择的花样再多也不怕,全部交给数据库处理就是。

使用道具 举报

回复
论坛徽章:
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
84#
发表于 2008-12-9 09:56 | 只看该作者
原帖由 yulihua49 于 2008-12-9 09:29 发表

这是我们的一种认证形态,dev也是这样的,你可以看到。
初态是空的,第一次登陆承认任何口令,并登记。以后必须口令符合。这虽然有一个安全漏洞,但简化了安全管理。口令是不可逆的,如果遗忘口令,没有任何人能知道,只有删除,再登录一次。从删除到再登录就是一个不安全窗口。

那个程序不要求你写,只要你知道我想干嘛就行。那些DAO如果用存储过程,仍然要提取到appserver,一点没节约,还给SRM带来很大困难。
认证还没有决定是否数字签名,如果签名,那个计算量是不得了的,让数据库引擎做太不划算了。
数据库引擎掌控着昂贵的盘阵,完整、准确、及时的提供存取服务才是正道,他在那忙于计算,耽误了别人的存取请求恐怕不划算。


为什么用存储过程没节约?我可不是用好多存储过程分别代替你的DAO, 我是用一个存储过程代替你整个模块。只要你提供所有的输入数据。这样只要一次调用就可以了,比你生成多条SQL怎么没有节约?

数字签名的计算也没什么大不了的,就像我上面所说,登录不是很密集的事务。
我也说了这些事情最好在数据库外面完成,我不是担心计算量,我是从安全角度考虑,凡是加密的东西经历的环节越少越好,最好就在客户端搞定。

使用道具 举报

回复
论坛徽章:
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
85#
发表于 2008-12-10 02:41 | 只看该作者


虽然你提供的信息不多,我还是把你15楼的代码改写成了存储过程。这个过程完成了取空白票、打上占用标记的功能,绝对是密集型事务的最佳选择。你尽可以用各种手段去测试并和你自己的程序对比。

我也很想看到你怎么证明这个存储过程会造成系统“堵车”。

关于数据格式的转换,例如输入、输出的日期格式,toJSON,我一向是主张不在数据库中完成的,但实在要这么做也未尝不可。你可以取完结果集再toJSON,这时模板就排上用场了,至于是静态模板还是动态模板随你选择。

结果集结构按你原来要求,虽然我认为没有必要字段所有都返回,特别是ROWID。
我不知道准确的表结构所以全部采用了VARCHAR2(20)。

刚刚模拟100个终端各自买100张票再转JSON格式,效果很好,1.5秒所有的JOB都结束了。明天我再进一步测试。

CREATE OR REPLACE TYPE tp_seat2 AS OBJECT (
      start_date            varchar2(20)
     ,beg_station           varchar2(20)
     ,train_no              varchar2(20)
     ,run_train             varchar2(20)
     ,on_date               varchar2(20)
     ,carno                 varchar2(20)
     ,seat_type             varchar2(20)
     ,seat_no               varchar2(20)
     ,end_station           varchar2(20)
     ,shortest_station      varchar2(20)
     ,purpose               varchar2(20)
     ,gride                 varchar2(20)
     ,pro                   varchar2(20)
     ,flag                  varchar2(20)
     ,used_dev              varchar2(20)
     ,used_uid              varchar2(20)
     ,used_time             varchar2(20)
     ,row_id                VARCHAR2(20)
     )
/

CREATE OR REPLACE TYPE tp_seat_table2 AS TABLE OF tp_seat2
/


CREATE OR REPLACE PROCEDURE getseat_for_sell (
                            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
   lv_flag       NUMBER;
   e_locked      EXCEPTION;
   PRAGMA EXCEPTION_INIT (e_locked, -54);
   lv_result tp_seat_table2 := tp_seat_table2();
   
BEGIN
   p_count := 0;
   
   FOR lv_rec IN (SELECT rowid AS row_id,seat.*
                    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
       lv_flag := NULL;
       BEGIN
          SELECT flag
            INTO lv_flag
            FROM seat
           WHERE rowid = lv_rec.row_id
           FOR UPDATE NOWAIT;
       EXCEPTION
          WHEN e_locked THEN
               lv_flag := NULL;
       END;
      
       IF lv_flag = 0 THEN
          UPDATE seat
             SET flag      =1
                ,used_time = SYSDATE
                ,used_uid  = p_userid
                ,used_dev  = p_devid
           WHERE rowid = lv_rec.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_rec.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_sell;
/


在看你的程序时我发现了一个问题。DTO_update生成UPDATE语句是怎么一个过程?假如我只修改其中一两个字段,你是UPDATE所有字段还是被修改的字段?如何处理“丢失更新”的问题?(即多用户环境中,某个修改被其他修改所覆盖)



[ 本帖最后由 newkid 于 2008-12-10 07:49 编辑 ]

使用道具 举报

回复
论坛徽章:
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
86#
 楼主| 发表于 2008-12-10 09:20 | 只看该作者
原帖由 newkid 于 2008-12-10 02:41 发表


虽然你提供的信息不多,我还是把你15楼的代码改写成了存储过程。这个过程完成了取空白票、打上占用标记的功能,绝对是密集型事务的最佳选择。你尽可以用各种手段去测试并和你自己的程序对比。

我也很想看到你怎么证明这个存储过程会造成系统“堵车”。

关于数据格式的转换,例如输入、输出的日期格式,toJSON,我一向是主张不在数据库中完成的,但实在要这么做也未尝不可。你可以取完结果集再toJSON,这时模板就排上用场了,至于是静态模板还是动态模板随你选择。

结果集结构按你原来要求,虽然我认为没有必要字段所有都返回,特别是ROWID。
我不知道准确的表结构所以全部采用了VARCHAR2(20)。

刚刚模拟100个终端各自买100张票再转JSON格式,效果很好,1.5秒所有的JOB都结束了。明天我再进一步测试。

CREATE OR REPLACE TYPE tp_seat2 AS OBJECT (
      start_date            varchar2(20)
     ,beg_station           varchar2(20)
     ,train_no              varchar2(20)
     ,run_train             varchar2(20)
     ,on_date               varchar2(20)
     ,carno                 varchar2(20)
     ,seat_type             varchar2(20)
     ,seat_no               varchar2(20)
     ,end_station           varchar2(20)
     ,shortest_station      varchar2(20)
     ,purpose               varchar2(20)
     ,gride                 varchar2(20)
     ,pro                   varchar2(20)
     ,flag                  varchar2(20)
     ,used_dev              varchar2(20)
     ,used_uid              varchar2(20)
     ,used_time             varchar2(20)
     ,row_id                VARCHAR2(20)
     )
/

CREATE OR REPLACE TYPE tp_seat_table2 AS TABLE OF tp_seat2
/


CREATE OR REPLACE PROCEDURE getseat_for_sell (
                            p_result      OUT SYS_REFCURSOR     ---- 结果集
                           ,p_count       OUT NUMBER            ---- 获得的票数。假如没有足够的票, 可能 p_xb AND seat_type = 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
       lv_flag := NULL;
       BEGIN
          SELECT flag
            INTO lv_flag
            FROM seat
           WHERE rowid = lv_rec.row_id
           FOR UPDATE NOWAIT;
       EXCEPTION
          WHEN e_locked THEN
               lv_flag := NULL;
       END;
      
       IF lv_flag = 0 THEN
          UPDATE seat
             SET flag      =1
                ,used_time = SYSDATE
                ,used_uid  = p_userid
                ,used_dev  = p_devid
           WHERE rowid = lv_rec.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_rec.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_sell;
/


在看你的程序时我发现了一个问题。DTO_update生成UPDATE语句是怎么一个过程?假如我只修改其中一两个字段,你是UPDATE所有字段还是被修改的字段?如何处理“丢失更新”的问题?(即多用户环境中,某个修改被其他修改所覆盖)


先回复再看。感谢!
昨天下午机器坏了。
这个地址中有数据结构:
http://space.itpub.net/8804348/viewspace-478471

dmp怎么用忘了,提示一下,给你些数据。

使用道具 举报

回复
论坛徽章:
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
87#
 楼主| 发表于 2008-12-10 09:42 | 只看该作者
原帖由 newkid 于 2008-12-10 02:41 发表



在看你的程序时我发现了一个问题。DTO_update生成UPDATE语句是怎么一个过程?假如我只修改其中一两个字段,你是UPDATE所有字段还是被修改的字段?如何处理“丢失更新”的问题?(即多用户环境中,某个修改被其他修改所覆盖)


seat_type*DECODE(p_xb,0,-1,1)    不懂。
另外,where里有表达式,是否会影响使用索引?,我原来的语句是要用索引的。不然在上亿行的表里太困难了。而且依主键一次排序再按order by二次排序,这可以以后细谈。

所有的语句,缺省只写where,当然做全行。如果做一部分,就自己写语句如:
int freeSeat(DAU *DP,char *day,char *devid,char *stmt)
{
        sprintf(stmt,"UPDATE %s.SEAT "
                "SET flag=0,USED_TIME=to_date('%s','%s') "
                "WHERE flag=1 and USED_DEV='%s'",
                        DP->SQL_Connect->DBOWN, day,YEAR_TO_SEC,
                        devid);
        return DAU_update(DP,stmt);
}
我没办法判断哪些列被修改过,所以要你自己写。我发现打头是'U',就不会生成了,直接用。好像前边说过。
特简单或特复杂的语句是要你自己处理的,我只自动生成一般的语句,符合20/80法则。不会‘丢失更新’,因为这条记录锁着呢,别人读不到。所有程序必须通过我这个服务驱动席位。都是要先 for update的。在隔离级0下,fetch一条锁一条,如果无修改,fetch下一条本条解锁,如果有修改,commit,rollback解锁。在隔离级1下全部活动集锁定。
为防止‘丢失更新’,必须读时锁。


ROWID是这样的:客户端调用这个服务,实际上就占用了这些票额,他可能要售出或退回,如果退回,就把ROWID送回来。
售出也要送回ROWID和其他参数。

检索条件里,flag=0,lv_flg似乎不用判断,不过你好像作为语句是否执行成功的标志。

lv_result tp_seat_table2 := tp_seat_table2(); 没懂,是建立临时表吗?

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

使用道具 举报

回复
论坛徽章:
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
88#
发表于 2008-12-10 10:05 | 只看该作者
你15楼有个: if(xb==0) strcat(stmt,"desc ");
所以我有这个:seat_type*DECODE(p_xb,0,-1,1) 作排序,我也不知道你为要这样。

关于索引,同一天发车,同一车次的记录有多少?我自己作了个(START_DATE,TRAIN_NO)的复合索引。WHERE里面如果已经有高效的条件,其他AND条件复杂一些不要紧。

如果你愿意提供测试数据,就用EXP导出DMP再压缩,传到某地方让我下载。

使用道具 举报

回复
论坛徽章:
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
89#
 楼主| 发表于 2008-12-10 10:14 | 只看该作者
原帖由 newkid 于 2008-12-10 10:05 发表
你15楼有个: if(xb==0) strcat(stmt,"desc ");
所以我有这个:seat_type*DECODE(p_xb,0,-1,1) 作排序,我也不知道你为要这样。

关于索引,同一天发车,同一车次的记录有多少?我自己作了个(START_DATE,TRAIN_NO)的复合索引。WHERE里面如果已经有高效的条件,其他AND条件复杂一些不要紧。

如果你愿意提供测试数据,就用EXP导出DMP再压缩,传到某地方让我下载。

create table seat (             /* 席位表 */
        start_date      date,   /* 始发日期 YYYY-MM-DD*/
        beg_station varchar2(4),        /* 上车站略码 */
        Train_no varchar2(12),  /* 全车次 */
        run_train       varchar2(6),    /* 运行车次 */
        on_date date,           /* 上车日期 YYYY-MM-DD HH24:MI*/
        Carno number(2),        /* 车厢号,不分车厢的票车厢号=0 */
        seat_type number(2),    /*席别,0=无号*/
        seat_no   number(3),    /* 席位号 */
        end_station number(3),  /* 顺号,售前是最远站,售后改为下车站 */
        shortest_station number(3),     /* 顺号,限售以远 */
        purpose number(9),              /* 用途 */
        gride   varchar2(50),   -- 事由码,新空调直达特快等。
        pro     char(5) null,   -- 席位属性码(靠窗,走道等
        flag    number(1),      /* 标志:0正常,1占用,2已售,3暂不可用,-1禁售 */
        used_dev varchar2(16) null, /* 最后操作终端 */
        used_uid varchar2(16) null, /* 最后操作人 */
        used_time date  null,           /* 最后操作时间 YYYY-MM-DD HH24:MI:SS */
        primary key(start_date,beg_station,Train_no,Carno,
                        seat_no,seat_type)
);
exp用法忘了,提示一下。

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

使用道具 举报

回复
论坛徽章:
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
90#
发表于 2008-12-10 10:20 | 只看该作者
呵呵我也不记得具体参数格式,你GOOGLE一下好了。

关于ROWID我还是不理解,如果有人退票你的ROWID从哪里来?难道是打在票上的?
你应该有一个唯一的流水号作主键的。

使用道具 举报

回复

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

本版积分规则 发表回复

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