Oracle JDBC事务管理和提交会话

时间:2011-03-10 14:27:57

标签: java oracle jdbc oracle10g session-state

假设我有以下代码

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;


    public class TestClass {

        public static void main(String args[]) throws ClassNotFoundException, SQLException{

            Connection database; 

            Class.forName("oracle.jdbc.driver.OracleDriver");
            database = 
                DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:mydb", "user", "pass");

            if (database.getAutoCommit())
                database.setAutoCommit(false);

            String insertParent = "Insert into ParentTable (parentId,name,value) values(parentSeq.nextval,?,?)";
            String insertChild = "Insert into ChildTable (childId,parentId,value) values(childSeq.nextval,?,?)";


            PreparedStatement addParentStmt = null;
            PreparedStatement addChildStmt  = null;

            //Add the parent record
            addParentStmt = database.prepareStatement(insertParent);

            addParentStmt.setString(1,"Fruit"); 
            addParentStmt.setString(2,"Orange");

            addParentStmt.executeUpdate();

            //Now retrieve the id of the parent row to insert into the child row

            Statement stmt  = null;
            ResultSet rs    = null;

            stmt = database.createStatement();
            rs = stmt.executeQuery("Select parentId from parentTable where value='Orange'");

            //Now insert into the child table

            addChildStmt = database.prepareStatement(insertChild );

            if(rs.next()){
                addChildStmt.setInt(1,rs.getInt("parentId"));
            }

            addChildStmt.setString(2,"The Orange child");

            addChildStmt.executeUpdate(insertChild);

            addChildStmt.close();
            addParentStmt.close();

            database.commit();

        }

    }

现在每次运行以上操作都会出现以下错误。

java.sql.SQLException: ORA-01008: not all variables bound

当我调试它时,异常位于addChildStmt.executeUpdate(insertChild)行;

我不想在插入父记录后发出提交。我的理解是,如果我参加同一场会议,我不必承诺。上面显示的第二个插入语句是否与第一个不在同一个会话中?为什么即使我刚刚插入记录,rs.next()也没有返回任何值?

由于

修改

要编译上面的代码,oracle中需要以下表格

create table ParentTable(parentId number, name varchar(20), value varchar(20));
create table childTable(childI number, parentid number, value varchar(20));

Oracle中还需要两个序列parentSeq和childSeq。

由于

1 个答案:

答案 0 :(得分:1)

由于这不是真正的代码,因此很难分辨出错误的位置。但策略本身是错误的:如果Orange不是唯一标识符,则无法运行。你应该

  1. 执行select语句以从父序列获取下一个值并获取父ID
  2. 执行insert语句以插入具有此父ID的父级
  3. 执行select语句以从子序列中获取下一个值并获取子ID
  4. 执行insert语句以插入具有父ID和子ID的子项。
  5. 已编辑:

    现在代码还可以,我找到了这个bug。替换

    addChildStmt.executeUpdate(insertChild);
    

    addChildStmt.executeUpdate();
    

    (并修复childId列的名称)。调试器或简单日志会显示select查询确实返回父ID。