|
使用自增多数是要用到id关联其他表,用序列的方式有一个缺点: 备份数据库后(用程序,不是在oracle内操作)再恢复的时候,id号继续累加,那么关联就全丢了,使用存储过程就不会发生这样的事情,而且并发访问的时候可能使你取出来的id号错误
用一个表sys_sequence,存储各表的表名、最大id号, 表结构: 名称------------------是否为空?-------类型 table_name-----------not null----------varchar2(30) cur_sequence-------not null----------number(5)
插入一条记录: insert into sys_sequence (table_name,cur_sequence) values ('news',0);
存储过程名:SYS_GET_SEQUENCE 内容: (as_table_name in varchar, next_sequence out number) as begin update sys_sequence set cur_sequence=cur_sequence + 1 where sys_sequence.table_name=as_table_name; select cur_sequence into next_sequence from sys_sequence where sys_sequence.table_name=as_table_name; end;
要对news表进行insert操作前,先update表sys_sequence的相关记录,使maxid+1,然后取出update后的id号,这个号即是将要插入到news表的新id号,然后就可在事务中进行其他处理了,处理完后commit,就禁止了并发访问造成的id关联不正确,备份再恢复的时候也不会出错
为了方便看程序,这里用jsp,有兴趣的朋友可以改成class: <%@ page language="java" contentType="text/html;charset=gb2312"%> <%@page import="java.sql.*"%> <html> <body> <table> <tr><td>aaa</td><td>bbb</td></tr> <%
try{
String driver = "oracle.jdbc.driver.OracleDriver"; String strUrl = "jdbc:oracle:thin:@192.168.1.XXX:1521:XXXXXX"; Class.forName(driver); Connection conn = DriverManager.getConnection(strUrl, "XXXX", "XXXXXXXXXX"); int i = 66; String procedure = "{call sys_get_sequence(?,?) }"; CallableStatement cstmt = conn.prepareCall(procedure); cstmt.registerOutParameter(2,java.sql.Types.INTEGER); cstmt.setString(1,"t");
cstmt.executeUpdate(); out.println("Procedure output is :"+cstmt.getInt(2));
Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select * from sys_sequence");
while(rs.next()) { out.println("<tr><td>" + rs.getString(1) + "</td><td>" + rs.getString(2) + "</td></tr>"); } //********************************* //其他操作 //*********************************** rs.close(); stmt.close(); conn.close(); %> </table> <p> <% out.print(conn.isClosed()); }catch(Exception e){ out.println(e); } %>
</body> </html> </body> </html>
|
|
|
|