Oracle JDBC 事务管理和提交会话

发布于 2024-10-21 17:11:52 字数 2599 浏览 4 评论 0原文

可以说我有以下代码

    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。

谢谢

Lets say i have the following bit of code

    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();

        }

    }

Now every time i run the above i get the following error.

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

When i debug it, the exception is at the line addChildStmt.executeUpdate(insertChild);

I dont want to issue a commit after i have inserted the parent record. My understanding is that i dont have to commit if i am on the same session. Will the second insert statement shown above not be in the same session as the first one? Why exactly is the rs.next() not returning any value even though i had just inserted the record?

Thanks

Edit

To compile the above code, The following tables will be required in oracle

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

And two sequences parentSeq and childSeq will also be required in Oracle.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

够钟 2024-10-28 17:11:52

由于这不是真正的代码,因此很难判断错误在哪里。但该策略本身是错误的:如果 Orange 不是唯一标识符,则它无法工作。您应该

  1. 执行 select 语句以从父序列中获取下一个值并获取父 ID
  2. 执行 insert 语句以插入具有此父 ID 的父对象
  3. 执行 select 语句以从子序列中获取下一个值并获取子 ID
  4. 执行插入语句以插入具有父 ID 和子 ID 的子 ID。

编辑:

现在代码没问题了,我发现了错误。替换

addChildStmt.executeUpdate(insertChild);

addChildStmt.executeUpdate();

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

Since this is not the real code, it's hard to tell where the bug is. But the strategy itself is wrong : if Orange is not a unique identifier, it can't work. You should

  1. execute a select statement to get the next value from the parent sequence and get a parent ID
  2. execute an insert statement to insert a parent with this parent ID
  3. execute a select statement to get the next value from the child sequence and get a child ID
  4. execute an insert statement to insert a child with the parent and child IDs.

EDITED :

Now that the code is OK, I have found the bug. Replace

addChildStmt.executeUpdate(insertChild);

with

addChildStmt.executeUpdate();

(and fix the name of the childId column). A debugger or a simple log would have shown that the select query does return the parent ID.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文