Невозможно найти сгенерированный ключ в Java с помощью метода getGeneratedKeys () в PreparedStatement - PullRequest
6 голосов
/ 03 апреля 2012

У меня следующий запрос:

String SQL = "insert into table (id, name) values (sequence.nextval, ?)";

Затем я делаю PreparedStatement следующим образом:

//initiate connection, statement etc
pStatement = connection.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
pStatement.setString(1,'blabla');

pStatement.executeUpdate();
ResultSet rs = pStatement.getGeneratedKeys();

while (rs.next()){
  //debugging here to see what rs has
}

При выполнении и отладке в этой точке отладки я вижу только свой ResultSetимеет один ключ, строку - совсем не то, что я ожидаю.При проверке базы данных все работает нормально, вставляются идентификаторы и все.Что-то в getGeneratedKeys (); меня смущает.

Что я делаю не так?

Заранее спасибо

Ответы [ 5 ]

10 голосов
/ 03 апреля 2012

Я ожидаю, что возвращаемый вами "ключ", который выглядит как строка, - это ROWID - это единственный ключ, который база данных генерирует напрямую.Вы должны иметь возможность изменить это, чтобы получить обратно столбец id (для этого, вероятно, требуется умеренно последняя версия драйвера JDBC).

//initiate connection, statement etc
String generatedColumns[] = {"ID"};
pStatement = connection.prepareStatement(SQL, generatedColumns);
pStatement.setString(1,'blabla');

pStatement.executeUpdate();
ResultSet rs = pStatement.getGeneratedKeys();

while (rs.next()){
  //debugging here to see what rs has
}

Вы также можете изменить свой запрос, чтобы явно добавить RETURNING пункт

String SQL = "insert into table (id, name) " + 
             "  values (sequence.nextval, ?) " + 
             "  returning id into ?";
1 голос
/ 03 апреля 2012

Я почти уверен, что getGeneratedKeys не вернет значение ключа, которое было инициализировано следующим значением последовательности. Действительно, в этом случае база данных не генерирует ключ сама по себе (как в случае столбца с автоинкрементом).

Если вы хотите узнать сгенерированный ключ, выполните первый запрос:

select sequence.nextval from dual

, а затем используйте результат этого первого запроса для выполнения подготовленного оператора:

insert into table (id, name) values (?, ?)
1 голос
/ 03 апреля 2012

Я думаю, что это:

pStatement.setString('blabla');

должно быть:

pStatement.setString(1, 'blabla');

Надеюсь, это поможет.

1 голос
/ 03 апреля 2012

Если это не работает, проблема может быть в sequence.nextval. Кажется, что если вы используете это, технически вы не генерируете ключ автоматически

0 голосов
/ 30 ноября 2012

В вашем коде есть ошибка: поскольку вы используете PreparedStatement, вы должны использовать собственную RETURN_GENERATED_KEYS константу:

pStatement = connection.prepareStatement(SQL, PreparedStatement.RETURN_GENERATED_KEYS);

Функция getGeneratedKeys() должна выполняться без проблем, и вы сможете получить ключи, сгенерированные в переменной ResultSet.

Таким образом, вам не нужно указывать имя для вашей строки (как предлагает решение Джастина, что довольно неплохо). Вам нужно только указать имя строки, если вы получаете доступ к полученным ключам, используя:

id = rs.getInt("id_row_name");

вместо:

id = rs.getInt(column_number); //One column for each key retrieved.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...