我看了一些帖子,大致有这样几种解决方案:
一、用oracle序列。可是跳号怎么解决??
2
二、我想用这个思路写,苦于对oracle不是很精通,有没有高人有这样的代码?给个参考,不胜感激。
1、建立一个序号表
2、在申请新的序列值的时候,先用Update将序列字段的值+1,但是不做commit,这样,相应的记录就被锁定;
3、判别SQLCode,如果成功,则说明这个序列值没有人使用,接着做4。不成功则提示稍候再试并Rollback;
4、用select取出序列值,+1后就是新的序列值;
5、把新序列值和相关数据进行对数据表的Insert,如果成功就接着做6。注意,对序号表的Update和对数据表的Insert是在一个事务里的,因此一旦对数据表的Insert操作失败而Rollback,则序号表的Update操作也被Rollback。这样一来,新的序列值并没有被真正commit到后台数据库里,还可以再一次使用,不会出现跳号的现象
6、commit。这样一来,数据表新增一条数据、序号表的相关序号+1。整个事务完成。

解决方案 »

  1.   

    有些数据库对序列号是自动增加的,有些需要建立一个序列对象(象ORACLE就需要自己创建)
    create sequence SEQ_LOG
    minvalue 1
    maxvalue 9999999999999999999
    start with 14015
    increment by 1
    cache 20
    cycle;
      

  2.   

    序列的创建语法就如楼上所示
    引用时:insert into tablename(序列字段,...) values(SEQ_LOG.next_val,...)
      

  3.   

    如果不使用序列,我习惯于将序列字段建为唯一索引字段且不允许为空。插入数据的操作为:
    insert into tablename(序列字段,...) select nvl(max(序列字段),1),... from tableme
      

  4.   

    在触发器中完成
    insert的时候+1
    delete的时候从他开始后退,不知道是不是这个意思!
      

  5.   

    用序列怎么解决跳号的问题:比如,在触发器中insert一条数据,到序列中获得一个加1的值,可是这条语句提交失败了,那样这个序列号不就浪费了?接着下面的自增号码就会跳号。
      

  6.   

    这个要靠程序控制阿
    并且好的程序都尽量不用序列号
    不方便移植什么的
    写段代码吧
    或者可以自己写一个类似于sequens的存储过程
      

  7.   

    insert into table values ( (select max(id) + 1 from table )....)
      

  8.   

    但是我上面的方法也是可能产生并发冲突的
    如果两个用户同时都做insert,发生在同一时间,insert进去的max(id) + 1就会相同,用sequence就不会发生这种情况
      

  9.   

    既然是序列,跳号又有什么问题呢?只要保证唯一即可。
    给个我用的代码片断,反正目前没有发现什么问题,也可能是因为并发访问比较少吧。
    public static synchronized String getNextId(String name)
            throws SQLException
        {
            String nextId = "";
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            name = name.toUpperCase();
            String sqlClause = String.valueOf(String.valueOf((new StringBuffer("select SERIAL_ID from SYS_SERIAL where TABLE_NM = '")).append(name).append("' ")));
            try
            {
                conn = DbBean.getConnection();
                conn.setAutoCommit(false);
                ps = conn.prepareStatement(sqlClause);
                rs = ps.executeQuery();
                if(rs.next())
                    nextId = rs.getString(1);
                if(nextId.length() == 0)
                    nextId = "1";
                for(int inti = nextId.length(); inti < 12; inti++)
                    nextId = "0".concat(String.valueOf(String.valueOf(nextId)));            ps.close();
                String sql = String.valueOf(String.valueOf((new StringBuffer("update SYS_SERIAL set SERIAL_ID=SERIAL_ID+1 where TABLE_NM='")).append(name).append("'")));
                Statement stmt = conn.createStatement();
                stmt.execute(sql);
                conn.commit();
                System.out.println(sql);
            }
            catch(SQLException e)
            {
                conn.rollback();
                throw e;
            }
            finally
            {
                DbBean.close(rs);
                DbBean.close(ps);
                DbBean.close(conn);
                return String.valueOf(nextId);
            }
        }要求有个表SYS_SERIAL(SERIAL_ID,TABLE_NM)
      

  10.   

    使用表级锁,结合
    insert into table values ( (select max(id) + 1 from table )....)
    可以搞定,但是有效率的问题。
    如果是前台展示用要求连续的话建议你用rownum+sequence,展示的时候用rownum,后台用sequence作唯一标识
      

  11.   

    可以建一个counter表
    在表中存放上一次的id
    例如:pid 1000
    下次使用时先从这个表中取值,程序控制用完+1再写入.
    不过要对失败情况判断更新pid
    取值函数如下:
    public BigDecimal getPID() {
        BigDecimal temp = new BigDecimal("0");
        // System.out.println("--------Counter table  starte-------");
        try {
          InitialContext ctx7 = new InitialContext();
          counterhome = (CounterHome) ctx7.lookup("Counter");
          counter = counterhome.findByPrimaryKey("pid");
          temp = counter.getId(); //get soolution id from Counter table
          System.out.println("Temp :" + temp.intValue());
          counter.setId(new BigDecimal(temp.intValue() + 1));
          System.out.println("after +1 temp :" + counter.getId());
        }
        catch (Exception e) {
          //  e.printStackTrace();
          System.out.println("not find");
          System.out.println("Counter table Error");
        }
        return temp;
      }  更新函数如下:public void setPID() {
        BigDecimal temp = new BigDecimal("0");
        // System.out.println("--------Counter table  starte-------");
        try {
          InitialContext ctx7 = new InitialContext();
          counterhome = (CounterHome) ctx7.lookup("Counter");
          counter = counterhome.findByPrimaryKey("pid");
          temp = counter.getId();
          counter.setId(new BigDecimal(temp.intValue() - 1));
          System.out.println("after - 1 :" + counter.getId());
        }
        catch (Exception e) {
          //  e.printStackTrace();
          System.out.println("not finddddd");
          System.out.println("Counter table Error");
        }
      }
      

  12.   

    oracle的sequence会有跳号,而且想通过oracle内部编程控制它,比较麻烦。
    一般用前端程序语言控制,比较容易,效率也较高。
    思路:
    db: create table t(id number,......)
    program:
      取得最大值赋值给一个变量:maxid=select max(id) from t
      insert 或update时,oracle有自动行级锁, id=maxid+1
      delete时,id号还可以重用。