Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Проверка наличия записи


Автор: nextzi0 3.10.2008, 15:54
Возможно ли в MySQL (5.0) одним запросом проверить, есть  ли определенная запись в базе (по полю `column` например) и если есть, то обновить это поле, если нету - то вставить новую запись?

Автор: skyboy 3.10.2008, 16:33
Цитата(nextzi0 @  3.10.2008,  14:54 Найти цитируемый пост)
есть  ли определенная запись в базе (по полю `column` например)

я так надеюсь, речь идет о поиску по полю с уникальными значениями? и с ключом unique по ним? тогда можно использовать http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html 
Код

insert ... on duplicate key update

Автор: solenko 3.10.2008, 17:14
А еще есть оператор REPLACE

Автор: skyboy 3.10.2008, 22:00
solenko, однако delete + insert изменит значение автоинкрементного поля. потому все возможные логические свзи нарушатся(если нет FK) или удалятся все связанные объекты(если есть FK). Так ведь?

Автор: bars80080 3.10.2008, 22:49
интересная тема, немного не догнал

у меня к примеру есть таблица, в которой есть колонка с уникальными идентификаторами заказов (комбинация букв и цифр)
мне надо вставить запись туда, но я заранее не знаю, а есть ли запись уже с таким идентификатором, приходится лишний раз проверять, а хотелось бы чтобы выполнялся запрос вставки с проверкой на существование и обновление, если обнаружится
я так понимаю, этот же вопрос и у nextzi0

а обязательно ли назначать ключ им? у меня стоит стандартный уникальный id автоинкремент, но ориентироваться в данном случае нужно по другому полю

Автор: skyboy 4.10.2008, 14:09
Цитата(bars80080 @  3.10.2008,  21:49 Найти цитируемый пост)
стандартный уникальный id автоинкремент

в данном случае это - главный ключ. 
Цитата(bars80080 @  3.10.2008,  21:49 Найти цитируемый пост)
а обязательно ли назначать ключ им?

т.е. ты хочешь, чтоб у тебя не было дубликатов значений в некоторых полях, но назначит unique index по ним тебе...эээ... лениво? 
да, обязательно должен быть уникальный индекс. посмотри на синтаксис:
Код

INSERT ... ON DUPLICATE KEY UPDATE

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

Автор: bars80080 4.10.2008, 19:52
Цитата(skyboy @  4.10.2008,  14:09 Найти цитируемый пост)
, но назначит unique index по ним тебе...эээ... лениво? 

ну почему лениво. долго читать документацию, которую я открою только может завтра, а может и через неделю, как со временем будет. оттого и спросил. потому на вопрос в конце, я могу ответить только: э-э-э-э...

Автор: solenko 4.10.2008, 19:56
Цитата(skyboy @  3.10.2008,  21:00 Найти цитируемый пост)
solenko, однако delete + insert изменит значение автоинкрементного поля. потому все возможные логические свзи нарушатся(если нет FK) или удалятся все связанные объекты(если есть FK). Так ведь?

http://dev.mysql.com/doc/refman/5.0/en/replace.html не выполняет операции удаления. Он делает в точности то же что и insert ... on duplicate key update, но только по первичному ключу.

Автор: skyboy 4.10.2008, 22:25
solenko, да, наверное я просто неверно понял 
Цитата

REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 12.2.5, “INSERT Syntax”. 

и
Цитата

REPLACE is a MySQL extension to the SQL standard. It either inserts, or deletes and inserts.

кстати, как раз по данной тобой ссылке.

Добавлено через 7 минут и 30 секунд
Код

create table test(
id int auto_increment primary key,
name varchar(32),
unique index(name)
);
insert into test(name) values('unique');
replace test(name) values('unique');
select * from test;

вернет
Цитата

id      name
2      unique

что показывает: запись была удалена и вставлена.

Автор: solenko 5.10.2008, 11:14
skyboy, читаем мой предидущий пост и видим "только по первичному ключу"
Код

mysql> create table test(id int auto_increment primary key, val varchar(255));
Query OK, 0 rows affected (0.18 sec)

mysql> REPlACE INTO test VALUES (null, '1111');
Query OK, 1 row affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 | 1111 |
+----+------+
1 row in set (0.02 sec)

mysql> REPLACE INTO test VALUES (1, '2222');
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT * FROM test;
+----+------+
| id | val  |
+----+------+
|  1 | 2222 |
+----+------+
1 row in set (0.00 sec)

Автор: skyboy 5.10.2008, 11:58
solenko, ну, так  правильно. то, что запись была удалена не возымеет никакого эффекта на значение автоинкрементного поля: мы же указываем явно значене для вставки. однако, это не означает, что запись не удаляется.
соответственно, можешь провести эксперимент с внешними ключами: просто ли replace "заменит" значение, или все же запись будет удалена и вставлена, что вызовет:
а)удаление всех записей в таблицах, имеющих внешний ключ на данную таблицу
б) вызов триггеров on before delete, on after delete, on before insert, on after insert

Добавлено через 44 секунды
или, думаешь, есть разница для replace - если дублируется первичный ключ, то удаление не происходит, а если просто по уникаьлному - то происходит?

Автор: solenko 5.10.2008, 12:29
чтот я тут недочитал ответ  Сейчас будем ставить эксперементы

Автор: XAKEPEHOK 24.3.2012, 11:05
Так вот все-таки, у меня есть таблица статистики, где нет уникальных полей. Есть дата, id пользователя, количество действий #1 и количество действий #2. 

Т.е. мне например, надо добавить +1 к количеству действий #2 за определенную дату, но я не знаю, может быть уже за эту дату было выполнено действие #1

Можно ли это реализовать одним запросом без введения уникальных полей? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)