2013-05-18 4 views
1

Я использую PreparedStatement для подготовки sql-запросов. Я хочу вставить строку в таблицу, если и только если она не существует.Вставить только в том случае, если строка не существует

Я попытался это -

INSERT INTO users (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ? 

Но это будет излишне обновлять USERID.

Как я могу вставить здесь userId?

+2

Пусть база данных вернет исключение на дубликат ключа и обработает его. –

+0

Ключевое слово, которое вы ищете, это 'UPSERT'. – OldCurmudgeon

ответ

2
INSERT INTO users 
     (userId) 
SELECT ? 
WHERE NOT EXISTS 
     (
     SELECT * 
     FROM users 
     where userId = ? 
     ) 
+0

IDK, но поскольку вы не получаете никаких повышений, я не могу понять, что лучше подходит ... ваш ответ или другой по _RiaD_? – XTop

+0

Мой ответ имеет более сложный SQL, ответ RiaD молча игнорирует ошибки преобразования. Есть что сказать и для обоих. – Andomar

+1

@Andomar. , , Я бы добавил, что это стандартный SQL. –

1

Вы можете использовать

INSERT IGNORE INTO users (userId) VALUES (?) 

Но вы должны понять, почему вы хотите игнорировать ошибки.

+1

Я не буду рекомендовать игнорировать ошибки. Их следует обрабатывать, а не игнорировать. –

+0

@LuiggiMendoza. Я понимаю, что его обычно нужно обрабатывать. Но если вам действительно нужно ничего не делать, если существует строка, собираетесь ли вы писать блок catch? – RiaD

+0

Я бы справился с Исключением. Это зависит от того, как результаты повлияют на приложение. Например, если пользователь вводит данные и пытается их сохранить, приложение должно отображать сообщение, например: * Извините, это запись дура * или что-то (конечно, я бы использовал формальное сообщение). Если это для стажера, я бы, по крайней мере, зарегистрировал исключение, а затем опубликовал стратегию о том, что делать: остановить процесс, просто продолжить предупреждение и т. Д. –

0

на дублированном ключе не работает правильно, когда таблица является innodb. Это создает именно проблему, которую вы описываете. Если вам нужна функциональность innodb, тогда вы должны сначала проверить существование строки, иначе вы можете преобразовать таблицу в таблицу myisam.

изменить: если вам необходимо проверить существование строки до принятия решения о вставке или обновлении, я бы посоветовал вам использовать хранимую процедуру.

DELIMITER // 
CREATE PROCEDURE adjustusers(IN pId int) 
BEGIN 
DECLARE userid int; 
    select count(id) into userid from users where id = pId; 
    if userid = 1 then 
    update users set id = pId where id = pId; 
    else 
    insert into users(id) values(pId); 
    end if; 
END // 
DELIMITER ; 

Хранимая процедура предварительно скомпилирована, как подготовленный отчет. Следовательно, нет проблем с вложением SQL-запросов и некоторой дополнительной функциональностью и только один вызов в базу данных.

+0

мои таблицы: 'innodb' :( – XTop

+0

Тогда у вас нет другого выбора, кроме того, сначала проверьте наличие строки: –