场景
数据迁移完成后需要对库中序列进行重置,。
方法
三种常见方式
删除--重建
这种方式下简单的序列重建会影响业务逻辑处理无法适应原有序列参数规则不一致的情况,但如果序列参数一致的情况下此种办法比较简单还有效率。
临时修改序列步长,而后还原(PL/SQL采用此种方式)
这种方式通过先修改序列步长然后通过NEXTVAL自增序列得到目标值,最后再将序列步长还原为原始值,如下SQL
- ALTER SEQUENCE SEQ_ACCOUNT_BALANCE INCREMENT BY 1000;
- SELECT SEQ_ACCOUNT_BALANCE.NEXTVAL FROM DUAL;
- ALTER SEQUENCE SEQ_ACCOUNT_BALANCE INCREMENT BY 1;
-
在修改某个具体序列时经常使用此方法,但如果批量操作序列则操作步骤较上一步要多了一步。
循环递增序列值
这种办法非常安全但低效率,如下SQL:
- FOR I IN 1 .. 1000 LOOP
- SELECT SEQ_ACC_ID.NEXTVAL INTO SAI FROM DUAL;
- END LOOP;
本人项目需求:
迁移数据,序列的初始值为数据表中序列对应主键ID的最大值。由于表和序列没有关联,本人将表、序列和主键值对应在配置文件中。如图:
主键ID,序列和表字段封装到一个实体类中,则读取出来存放到List中。
将List的值转变成执行的SQL语句,在此,一个序列改变初始值,则删除序列和创建序列同时执行,我是将执行一个序列的这两个语句放在数组里,则多个序列则存数组的集合
Controller.java
//start 改变序列的初始值
try {
//获取数据
List<SequenceMessage> seqmessageList = ParseXml.getSequenceList();
Map<String, List<String>> resultmap = baseservice.doWork(seqmessageList);
logsb.append("序列初始值改变<BR>总共序列个数"+seqmessageList.size()+"<br>");
List<String> falseResult = resultmap.get("false");
List<String> trueResult = resultmap.get("true");
logsb.append("执行序列错误有"+falseResult.size()+"个,执行序列正确有"+trueResult.size()+"个,无数据表"+(seqmessageList.size()-falseResult.size()-trueResult.size())+"<br>");
if(falseResult.size() > 0){
logsb.append("失败执行语句以下有:<br>");
for (int i = 0; i < falseResult.size(); i++) {
logsb.append(falseResult.get(i)+"<br>");
}
}
if(trueResult.size() >0){
logsb.append("正确执行语句以下有:<br>");
for (int i = 0; i < trueResult.size(); i++) {
logsb.append(trueResult.get(i)+"<br>");
}
}
} catch (Exception e) {
logsb.append("改变序列初始值发生异常:"+e.toString()+"<br><br>");
e.printStackTrace();
}
baseservice.java
public Map<String, List<String>> doWork(List<SequenceMessage> seqmessageList){
Connection conn = getConnection();
Map<String, List<String>> resultmap = new HashMap<String, List<String>>();
List<String> falseResult = new ArrayList<String>();
List<String> trueResult = new ArrayList<String>();
//start 获取表和序列和字段之间的关系
List<String[]> seqDDLArray = new ArrayList<String[]>();
for (int i = 0; i < seqmessageList.size(); i++) {
SequenceMessage seqmsg = seqmessageList.get(i);
String id = seqmsg.getId();
String tname = seqmsg.getTablename();
String seqname = seqmsg.getSeqname();
String maxsql = "select max(" + id + ") from " + tname;
// 执行根据该主键ID获取该对应表中的最大值
Object[] obj = null;
try {
obj = (Object[]) basedao.queryForArrayList(maxsql).get(0);
String objstr = obj[0] + "";
if (!"null".equals(objstr)) {
seqDDLArray.add(rebuildSEQ(seqname,Integer.parseInt(objstr)));
}
} catch (Exception e) {
e.printStackTrace();
falseResult.add(e.toString());
continue;
}
}
//start 循环执行删除序列和创建序列
for (int i = 0; i < seqDDLArray.size(); i++) {
//同一个序列 删除和创建同时执行
String[] sqlattr=seqDDLArray.get(i);
try {
boolean flag =basedao.updateBatch(sqlattr, conn);
if(!flag){
for (int j = 0; j <sqlattr.length; j++) {
falseResult.add(sqlattr[j]);
}
}else{
for (int j = 0; j <sqlattr.length; j++) {
trueResult.add(sqlattr[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
resultmap.put("false", falseResult);
resultmap.put("true", trueResult);
DbUtils.closeQuietly(conn);
return resultmap;
}
basedao.java
/**
* 执行批量
*
* @param sqlArray
* @throws SQLException
*/
public boolean updateBatch(String[] sqlArray, Connection conn)
throws SQLException {
boolean flag = false;
conn.setAutoCommit(false);
Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
for (String tmpSql : sqlArray) {
stmt.addBatch(tmpSql);
}
int[] rtnArr = stmt.executeBatch();
conn.commit();
if (rtnArr.length > 0) {
flag = true;
}
return flag;
}
返回类型是由于我需求是要将后台代码返回给前端展示,就直接在后台拼接代码了。代码应该可以看懂
我这个代码是执行一个序列的操作不成功,继续走下一步,错误和正确执行的返回给客户端展示
界面就不展示了
参照http://blog.csdn.net/a316212802/article/details/40297115
相关推荐
Java的JDBC提供了接口和类来与Oracle数据库交互,如`java.sql.Connection`、`java.sql.Statement`、`java.sql.PreparedStatement`等,通过这些接口,开发者可以在Java程序中创建、使用序列和同义词。 综上所述,...
首先,Oracle Sequence是Oracle数据库提供的一种序列号生成器,它能够按照预设的步长和起始值生成唯一的数字,常用于生成主键值。在创建表时,我们并不会直接在表定义中指定主键自增,而是先创建一个Sequence,然后...
- **创建序列**: `CREATE SEQUENCE 序列名 START WITH 起始值 INCREMENT BY 步长 MAXVALUE 最大值 MINVALUE 最小值 CYCLE | NOCYCLE CACHE 缓存大小 NOCACHE;` - **使用序列**: 通过`NEXTVAL`和`CURRVAL`伪列获取...
在数据库对象创建完成后,我们可以开始编写应用程序,通常采用面向对象编程语言,如Java或C#,结合Oracle的JDBC驱动进行数据访问。应用开发包括用户界面设计、业务逻辑实现以及数据库操作接口。例如,开发借阅功能时...
可以使用ODBC或JDBC等技术连接到其他数据源,并通过FORMS进行数据交互。例如,使用 `ODBC-QUERY` 函数从外部数据源检索数据。 #### 43. FORMS4.5实现的列表查询、多行录入中的实现行累计 可以使用 `LOOP` 和 `SUM`...