Firebird + JDBC: получение сгенерированного ключа из вставки - PullRequest
2 голосов
/ 30 сентября 2011

Похоже, что Firebird НЕ поддерживает getGeneratedKeys () после выполнения вставки со столбцом auto_increment. Поэтому я хотел бы понять, как я могу получить сгенерированный ключ после вставки.

1) Должен ли я использовать «вставлять в пользователи (...) значения (...) возвращающий идентификатор» и вызывать его через CallableStatement, чтобы получить сгенерированный идентификатор? Как именно? Нужно ли мне обернуть мою вставку вокруг "call {...}"

2) Есть ли другой способ получения сгенерированного идентификатора в Firebird, что-то вроде «select last_id_generated ()». «Выберите max (id) из пользователей» не считается.

3) Правда ли, что getGeneratedKeys () не поддерживается драйвером JDBC Firebird? (По желанию)

Спасибо!

Ответы [ 4 ]

2 голосов
/ 30 сентября 2011

Оказывается, все, что вам нужно сделать, это вызвать "вставка ... возврат" с executeQuery (из PreparedStatement) вместо executeUpdate.Это вернет ваш ResultSet, откуда вы можете получить сгенерированный идентификатор.Я никогда не думал, что вы можете вызвать INSERT с executeQuery.Я думал, тебе нужно выполнить executeUpdate.

2 голосов
/ 22 октября 2012

Я использую конструкцию для получения значения первичного ключа:

String buf =       
             "SELECT GEN_ID ( <YOUR_ID_NAME*>, 0 ) " + //see description below
             "FROM RDB$DATABASE";
try
{
    Statement stm = conn.createStatement ();
    ResultSet RS = stm.executeQuery ( buf );
    buf = null;
    if ( RS != null )
    {
        RS.next ();
        buf = RS.getString ( 1 ).trim (); //That is it
        RS.close ();
    }
}
catch ( SQLException e )
{}

Теперь buf содержит идентификатор

< *> - Вы можете увидеть это с помощью IBExpert.

0 голосов
/ 04 апреля 2015

Добавлена ​​поддержка getGeneratedKeys в Jaybird 2.2. Существуют некоторые предостережения: метод RETURN_GENERATED_KEYS по умолчанию вернет все столбцы таблицы, поэтому вы должны извлечь столбцы из результирующего набора по имени столбца или использовать один из методов, чтобы явно указать индекс столбца. или имя столбца, см. примечания к выпуску Jaybird (2.2.7) для получения более подробной информации.

Чтобы ответить на ваши оригинальные вопросы:

  1. Когда вы выполняете INSERT ... RETURNING ..., вам нужно использовать executeQuery (или execute) и обрабатывать набор результатов, как если бы вы выполняли нормальный SELECT. С Jaybird 2.2 вы также можете использовать executeUpdate, если вы используете RETURN_GENERATED_KEYS и получить набор результатов из getGeneratedKeys()

  2. Использование INSERT ... RETURNING ... или getGeneratedKeys - единственный способ получить сгенерированное значение для этого оператора, все другие методы (например, SELECT GEN_ID(GEN_NAME,0) FROM RDB$DATABASE) не могут быть доверенными, поскольку последовательности находятся вне контроля транзакций и возвращаемого значения возможно, был сгенерирован для другой параллельной транзакции.

  3. В то время, когда вы задавали этот вопрос, Jaybird действительно не поддерживал его (2.1.6).

Раскрытие: я один из разработчиков Jaybird.

0 голосов
/ 30 сентября 2011

будет получено текущее поколение

SELECT GEN_ID(GEN_NAME,0) FROM RDB$DATABASE

, а GEN_NAME - это то, что вы назвали этим поколением

, когда вы создаете поле автоинкремента триггера и создается поколение, триггер выглядит такобычно это

SET TERM ^^ ;
CREATE TRIGGER TABLE_BEFOREINSERT FOR TABLE ACTIVE BEFORE INSERT POSITION 0 AS
BEGIN

  if ( new.ID is null )
  then new.ID = gen_id(GEN_TABLE, 1);

END ^^
SET TERM ; ^^

и создание для генерации выглядит следующим образом:

CREATE GENERATOR GEN_TABLE;
SET GENERATOR GEN_TABLE TO 32;

эти два вместе составляют так, что перед вставкой новой строки он проверяет, указали ли вызначение ID, если нет, увеличивает генерацию на единицу, получает текущее значение и помещает его в столбец идентификатора

...