Oracle JDBC управление транзакциями и фиксация сессий - PullRequest
0 голосов
/ 10 марта 2011

Допустим, у меня есть следующий бит кода

    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 Ответ

1 голос
/ 10 марта 2011

Так как это не настоящий код, трудно сказать, где ошибка. Но сама стратегия неверна: если Orange не является уникальным идентификатором, он не может работать. Вы должны

  1. выполнить оператор выбора, чтобы получить следующее значение из родительской последовательности и получить родительский идентификатор
  2. выполнить оператор вставки для вставки родителя с этим родительским идентификатором
  3. выполнить оператор выбора, чтобы получить следующее значение из дочерней последовательности и получить дочерний идентификатор
  4. выполнить оператор вставки для вставки дочернего элемента с родительским и дочерним идентификаторами.

отредактировано:

Теперь, когда код в порядке, я нашел ошибку. Заменить

addChildStmt.executeUpdate(insertChild);

с

addChildStmt.executeUpdate();

(и исправьте имя столбца childId). Отладчик или простой журнал показали бы, что запрос на выборку возвращает родительский идентификатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...