我看了一些帖子,大致有这样几种解决方案:
一、用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。整个事务完成。
一、用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。整个事务完成。
解决方案 »
- 不想grouping的欄位,但卻要select進去,如何寫呢?
- 查找查询结果中存在的特定序列问题
- 可否使用觸發器剔除批量插入的數據中的重複主鍵數據而不引發異常
- 哪里能下载到ORACLE9.2.0.4 for linux的patch文件?
- 如何自己设定oracle 的jobs的名字?
- 怎么把别人数据库实例里面的东西全导入到自己的oralce里面呀
- 切取字符串问题:
- 哪里可以下载Oracle 8i/9i/10i?
- 怎么在pl/sql语句中加入sqlplus的connect命令?
- 一个用户如何才能访问另一个用户下的对象(比如SELECT * FROM USER1.TABLE1)?
- 正常操作数据库N次后,现在 要恢复到其中的第J(j<N)次时的数据状态。问:用事务回滚可以实现么
- 在UNIX 下 如何限制ORACLE登陆的网段,让别的网段不能登陆!!!!!
create sequence SEQ_LOG
minvalue 1
maxvalue 9999999999999999999
start with 14015
increment by 1
cache 20
cycle;
引用时:insert into tablename(序列字段,...) values(SEQ_LOG.next_val,...)
insert into tablename(序列字段,...) select nvl(max(序列字段),1),... from tableme
insert的时候+1
delete的时候从他开始后退,不知道是不是这个意思!
并且好的程序都尽量不用序列号
不方便移植什么的
写段代码吧
或者可以自己写一个类似于sequens的存储过程
如果两个用户同时都做insert,发生在同一时间,insert进去的max(id) + 1就会相同,用sequence就不会发生这种情况
给个我用的代码片断,反正目前没有发现什么问题,也可能是因为并发访问比较少吧。
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)
insert into table values ( (select max(id) + 1 from table )....)
可以搞定,但是有效率的问题。
如果是前台展示用要求连续的话建议你用rownum+sequence,展示的时候用rownum,后台用sequence作唯一标识
在表中存放上一次的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");
}
}
一般用前端程序语言控制,比较容易,效率也较高。
思路:
db: create table t(id number,......)
program:
取得最大值赋值给一个变量:maxid=select max(id) from t
insert 或update时,oracle有自动行级锁, id=maxid+1
delete时,id号还可以重用。