JDBC - INSERT и возвращать сгенерированный идентификатор, или если DUPLICATE KEY возвращает старый идентификатор - PullRequest
0 голосов
/ 13 октября 2011

Название довольно ясно ... Я хочу иметь возможность добавить элемент в базу данных, и если уже есть элемент с соответствующим уникальным столбцом, вернуть идентификатор этого элемента ...

Приведенное ниже выражение настолько близко, насколько я нашел, к решению

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

Мне удалось получить новый идентификатор (при вставке новой строки) с помощью Statement.generatedKeys ().будет ли "id" появляться в Statement.generatedKeys () в случае дублирования?если нет, то как я могу получить его?

ОБНОВЛЕНИЕ : с помощью хранимой процедуры, именно то, что мне нужно:

INSERT INTO applications (path, displayName) VALUES (?, ?) 
ON DUPLICATE KEY UPDATE 
   id = LAST_INSERT_ID(id), path = ?, displayName = ?;
SELECT LAST_INSERT_ID() INTO ?;

Это работает на другом проекте яя работаю над тем, что использует MySQL Connector в .NET, но, к сожалению, хранимая процедура не подходит для меня в этом проекте Java.

Есть ли какой-либо другой способ отправить 2 оператора в одной сетевой поездке?

Ответы [ 3 ]

2 голосов
/ 06 декабря 2013

Итак, у меня было такое же требование, как и у ОП. То, как Mysql обрабатывает INSERT ... ON DUPLICATE KEY UPDATE, - просто глупо, но, к сожалению, нам приходится с этим мириться. Когда вы используете ON DUPLICATE на Mysql 5.5 или выше, если вставка происходит без дубликатов, JDBC возвращает счетчик 1 и идентификатор вновь вставленной строки. Если выполненное действие является обновлением из-за дублирования, JDBC возвращает счетчик 2, а также идентификатор исходной строки и вновь созданный идентификатор, даже если новый идентификатор никогда не вставляется в таблицу.

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

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;

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

Long key;
ResultSet keys = preparedStatement.getGeneratedKeys();
if (keys.next())
    key = keys.getLong("GENERATED_KEY");
2 голосов
/ 13 октября 2011

Это кажется правдоподобным

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=3;

, но это кажется безумным:

INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

Не могли бы вы обновить поле идентификатора существующей записи?Что будет с этими записями, ссылающимися на эту?

В любом случае, догадайтесь, в случае нормального обновления (первого) statement.generatedKeys() не вернет уже существующий идентификатор.В этом случае вам, вероятно, придется выполнить дополнительный оператор выбора (со столбцами уникальных ключей в предложении where: select id from table where a=1 and b=2), чтобы узнать идентификатор записи.

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

0 голосов
/ 13 октября 2011

Если ваша цель - предотвратить дублирование записей, вы можете настроить свою таблицу с помощью первичного ключа / УНИКАЛЬНОЕ ограничение . Затем вы можете выбрать один из следующих путей в вашем коде:

  1. Программно проверить уникальность строки, которую вы собираетесь добавить, и обработать случай, когда эта строка уже существует в таблице
  2. Попробуйте вставить новую строку. Если это дубликат, попытка не удастся с исключением, и вы можете найти старую строку, используя тот же критерий. Я думаю, что это плохой подход.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...