JDBC读取新插入Oracle数据库Sequence值的5种方法

SAP-MM:SAP MM(物料管理)模块 的系统化学习计划 SAP MM模块的系统化学习计划 阅读详情

JDBC读取新插入Oracle数据库Sequence值的5种方法


      Oracle的sequence实现非常灵活,所以也带来一些易用性问题,如何取到新插入记录生成的sequence值与其它数据库有较大差别,本文详国介绍了5种实现读取新插入记录sequence值的方法。

测试用的数据库脚本:

SQL> create table T1
  2  (
  3    ID NUMBER
  4  );
 
Table created
SQL> create sequence SEQ_T1;
 
Sequence created

//公共代码:得到数据库连接
public Connection getConnection() throws Exception{
	Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
	Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:dbname", "username", "password");
	return conn;
}

//方法一
//先用select seq_t1.nextval as id from dual 取到新的sequence值。
//然后将最新的值通过变量传递给插入的语句:insert into t1(id) values(?) 
//最后返回开始取到的sequence值。
//这种方法的优点代码简单直观,使用的人也最多,缺点是需要两次sql交互,性能不佳。
public int insertDataReturnKeyByGetNextVal() throws Exception {
	Connection conn = getConnection();
	String vsql = "select seq_t1.nextval as id from dual";
	PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);
	ResultSet rs=pstmt.executeQuery();
	rs.next();
	int id=rs.getInt(1);
	rs.close();
	pstmt.close();
	vsql="insert into t1(id) values(?)";
	pstmt =(PreparedStatement)conn.prepareStatement(vsql);
	pstmt.setInt(1, id);
	pstmt.executeUpdate();
	System.out.print("id:"+id);
	return id;
}

//方法二
//先用insert into t1(id) values(seq_t1.nextval)插入数据。
//然后使用select seq_t1.currval as id from dual返回刚才插入的记录生成的sequence值。
//注:seq_t1.currval表示取出当前会话的最后生成的sequence值,由于是用会话隔离,只要保证两个SQL使用同一个Connection即可,对于采用连接池应用需要将两个SQL放在同一个事务内才可保证并发安全。
//另外如果会话没有生成过sequence值,使用seq_t1.currval语法会报错。
//这种方法的优点可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码,缺点是需要两次sql交互,性能不佳,并且容易产生并发安全问题。
public int insertDataReturnKeyByGetCurrVal() throws Exception {
	Connection conn = getConnection();
	String vsql = "insert into t1(id) values(seq_t1.nextval)";
	PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);
	pstmt.executeUpdate();
	pstmt.close();
	vsql="select seq_t1.currval as id from dual";
	pstmt =(PreparedStatement)conn.prepareStatement(vsql);
	ResultSet rs=pstmt.executeQuery();
	rs.next();
	int id=rs.getInt(1);
	rs.close();
	pstmt.close();
	System.out.print("id:"+id);
	return id;
}

//方法三
//采用pl/sql的returning into语法,可以用CallableStatement对象设置registerOutParameter取得输出变量的值。
//这种方法的优点是只要一次sql交互,性能较好,缺点是需要采用pl/sql语法,代码不直观,使用较少。
public int insertDataReturnKeyByPlsql() throws Exception {
	Connection conn = getConnection();
	String vsql = "begin insert into t1(id) values(seq_t1.nextval) returning id into :1;end;";
	CallableStatement cstmt =(CallableStatement)conn.prepareCall ( vsql); 
	cstmt.registerOutParameter(1, Types.BIGINT);
	cstmt.execute();
	int id=cstmt.getInt(1);
	System.out.print("id:"+id);
	cstmt.close();
	return id;
}

//方法四
//采用PreparedStatement的getGeneratedKeys方法
//conn.prepareStatement的第二个参数可以设置GeneratedKeys的字段名列表,变量类型是一个字符串数组
//注:对Oracle数据库这里不能像其它数据库那样用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,这种语法是用来取自增类型的数据。
//Oracle没有自增类型,全部采用的是sequence实现,如果传Statement.RETURN_GENERATED_KEYS则返回的是新插入记录的ROWID,并不是我们相要的sequence值。
//这种方法的优点是性能良好,只要一次sql交互,实际上内部也是将sql转换成oracle的returning into的语法,缺点是只有Oracle10g才支持,使用较少。
public int insertDataReturnKeyByGeneratedKeys() throws Exception {
	Connection conn = getConnection();
	String vsql = "insert into t1(id) values(seq_t1.nextval)";
	PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql,new String[]{"ID"});
	pstmt.executeUpdate();
	ResultSet rs=pstmt.getGeneratedKeys();
	rs.next();
	int id=rs.getInt(1);
	rs.close();
	pstmt.close();
	System.out.print("id:"+id);
	return id;
}

//方法五
//和方法三类似,采用oracle特有的returning into语法,设置输出参数,但是不同的地方是采用OraclePreparedStatement对象,因为jdbc规范里标准的PreparedStatement对象是不能设置输出类型参数。
//最后用getReturnResultSet取到新插入的sequence值,
//这种方法的优点是性能最好,因为只要一次sql交互,oracle9i也支持,缺点是只能使用Oracle jdbc特有的OraclePreparedStatement对象。
public int insertDataReturnKeyByReturnInto() throws Exception {
	Connection conn = getConnection();
	String vsql = "insert into t1(id) values(seq_t1.nextval) returning id into :1";
	OraclePreparedStatement pstmt =(OraclePreparedStatement)conn.prepareStatement(vsql);
	pstmt.registerReturnParameter(1, Types.BIGINT);
	pstmt.executeUpdate();
	ResultSet rs=pstmt.getReturnResultSet();
	rs.next();
	int id=rs.getInt(1);
	rs.close();
	pstmt.close();
	System.out.print("id:"+id);
	return id;
}

     以上5种方法都可以实现功能,以下是5种方法的优缺点汇总,个人推荐性能要求一般的业务采用第一种方法,性能要求非常高业务采用第五种方法。

方法

简介

优点

缺点

方法一

先用seq.nextval取出值,然后用转入变量的方式插入

代码简单直观,使用的人也最多

需要两次sql交互,性能不佳

方法二

先用seq.nextval直接插入记录,再用seq.currval取出新插入的值

可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码

需要两次sql交互,性能不佳,并且容易产生并发安全问题

方法三

用pl/sql块的returning into语法,用CallableStatement对象设置输出参数取到新插入的值

只要一次sql交互,性能较好

需要采用pl/sql语法,代码不直观,使用较少

方法四

设置PreparedStatement需要返回新值的字段名,然后用getGeneratedKeys取得新插入的值

性能良好,只要一次sql交互

只有Oracle10g才支持,使用较少

方法五

returning into语法,用OraclePreparedStatement对象设置输出参数,再用getReturnResultSet取得新增入的值

性能最好,因为只要一次sql交互,oracle9i也支持

只能使用Oracle jdbc特有的OraclePreparedStatement对象

 
 

作者:叶正盛

日期:2011-10-30

我的新浪微博:http://weibo.com/yzsind


华为OD机试真题 新系统 2026-09-06 Python&JS【仓储货物有序出库】 某仓储中心有一个货物堆放区,货物编号按乱序堆叠存放,只能从顶部取货,管理员需要将货物按编号从小到大取出。 阅读详情

相关推荐

XGBoost实战:从原理到调参,手把手教你提升模型性能(附Python代码)

本文深入解析XGBoost核心原理,并提供一套从数据准备、系统性调参到生产部署的完整实战指南。通过剖析目标函数、正则化项与分裂算法,帮助读者理解参数背后的数学逻辑,并利用交叉验证、早停法及自动化工具(如Optuna)高效提升模型性能。文中附有详尽的Python代码示例,涵盖类别特征处理、缺失值应对、不平衡数据调整及模型可视化等高级技巧。

weixin_29178069的博客 457

mysql mybatis 函数_mysql和oracle的mybatis操作

1.Oracle、MySQL插入时返回下一个主键的操作Oracle:SELECT SEQ_ROLE.NEXTVAL AS ID FROM DUALinsert into ROLE(ID, NAME, CREATE, MODIFY) values (#{id}, #{name}, sysdate, sysdate)注意:这边的keyProperty="id"中"id"指的是Java对象ROLE中的属...

weixin_36074841的博客 595

【MIT-BEVFusion代码解读】第四篇:融合特征fuser和解码特征decoder

的大小,实际上源代码也是这么做的。最后将得到两个分支的特征进行。,第一个特征使用卷积降低通道数即可,第二个则需要反卷积来提升。所以backbone只有两个分支,都是5个卷积模块组成。的长和宽都减半至90,然后在经过5个相同的。将通道降至128,后面再接5个相同的。,将通道数128上至256,并且将。特征进行融合,这里使用的。部分由两部分组成,分别是。,这个分支首先经过第一个。,然后再卷积得到 =>提取特征,最后得到特征。得到了两个大小不同的。

非晚非晚的博客 2954

Oracle数据库:序列sequence的创建,查询,修改,删除,increment by,start with等关键字

Oracle数据库:序列sequence的创建,查询,修改,删除,increment by,start with等关键字

weixin_46838716的博客 3784

自适应粒子群优化(Adaptive Particle Swarm Optimization,APSO

下面是一个关于自适应粒子群优化(Adaptive Particle Swarm Optimization,APSO)的博客,希望可以帮助您。提示:以下是本篇文章正文内容,下面案例可供参考在上面的代码中,表示粒子的数量,表示解空间的维度,表示迭代次数,表示优化的目标函数。在__init__方法中,我们初始化了粒子群的位置和速度,并将每个粒子的位置作为其最优解,将其适应度值初始化为正无穷。我们还初始化了学习因子和惯性权重的参数。在run方法中,我们迭代了次,计算每个粒子的适应度值和最优解。

weixin_52026057的博客 9914

阿里云一键登录Java后端实战:5分钟搞定号码认证服务集成(附完整代码)

本文详细介绍了如何在Java后端项目中快速集成阿里云号码认证服务(PNVS),实现高效、安全的一键登录功能。文章从核心架构、安全机制解析入手,提供了完整的Maven依赖配置、服务端环境准备、核心业务逻辑实现(包括Token验证、用户处理、异常降级)以及生产环境下的性能优化、监控与部署方案,并附有可直接使用的完整代码示例。

p1q2r的博客 844

mysql数据库+查询+sequence_MySQL Using Sequences

序列就是按照要求的顺序产生的一组整数,比如1、2、3……这样。数据库中经常会用到序列,因为很多应用程序都会需要让表中的每行的值唯一,而使用序列就可以轻松地解决这个问题。下面就来介绍 MySQL 中的序列使用。使用 AUTO_INCREMENT 列在MySQL中,序列最简单的用法就是将一列定义为 AUTO_INCREMENT ,然后让 MySQL 来处理剩下的任务。范例在下面这个范例中,先创建一个表...

weixin_34603379的博客 1161

从ARCore到AICore:揭秘Google如何通过系统级服务推动Android生态创新

本文深入探讨了Google如何通过AICore等系统级服务推动Android生态创新。从ARCore到AICore,Google通过分层解耦策略将AI能力下沉至系统层,实现端侧大模型推理,如Gemini Nano在Pixel 8 Pro中的应用。文章剖析了AICore的技术架构、开发者赋能路径及场景化实践,展示了其在通信、内容创作和生产力工具中的卓越表现。

rust6ferris的博客 545

JdbcTemplate入门

1.1 创建项目 项目名: spring-jdbc 引入jar包 [外链图片转存失败(img-LRw3KPXo-1565088030915)(pic\1506678212941.png)] <dependencies> <dependency> <groupId>junit</groupId> <...

weixin_43343423的博客 414

UG NX二次开发(C#)-外部模式-批量删除某些图层中的体对象和曲线对象

在 UG NX中,有时需要批量删除某文件夹下多个.prt文件中固定一些图层中的体对象和曲线对象,这时如果采用手动逐个打开模型,并选择针对的图层删除,即耗时也容易遗漏,因此采用外部模式来处理比较方便。本文介绍批量删除某些图层中的体对象和曲线对象。

GimiGimmy 3035

小卫星多普勒频偏MATLAB代码

多普勒频偏是由于发射机和接收机之间的相对运动而引起的频率变化。对于小卫星,由于其速度和高度的变化,多普勒频偏会变得更加明显。本文将探讨小卫星多普勒频偏的原理、影响因素以及补偿方法。多普勒频偏的原理当发射机和接收机之间存在相对运动时,接收到的信号频率会发生变化。这种频率变化称为多普勒频偏。其原理可以描述如下:设发射机和接收机之间的距离为 d,发射信号的频率为 f0,发射机和接收机的相对速度为 v。则接收到的信号频率 f 为:其中 c 为光速。

qq_59747472的博客 244

java代码读取dbsequence的值_JDBC读取新插入Oracle数据库Sequence值的5种方法

/公共代码:得到数据库连接publicConnectiongetConnection()throwsException{Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();Connectionconn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1 :...

weixin_29111277的博客 240

Marvell 88Q6113 如何制作一个完整的量产固件88Q6113_flash.bin并进行烧录

本章节介绍如何基于Marvell工具链,制作一个完整的量产固件88Q6113_flash.bin,集成用户自定义的配置文件 config.bin,用于88Q6113的Flash烧录。注:Marvell 88Q5072 与 Marvell 88Q6113 的配置流程是一样的。

老板来份猪脚拼叉烧的博客 2008
上一篇: 关于数据库Varchar字段类型长度设计问题
下一篇: HTC G7 相机故障,自己动手维修详细步骤
yzsind
博客等级 码龄25年 1925粉丝 328原创
评论 19
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值