У меня есть таблица с именем user_ips
чтобы отслеживать пользователей в случае удаления их файлов cookie или изменения браузера. Так или иначе, следующий код прост. Он обновляет записи в user_ips, которые равны идентификатору пользователя и IP. Если запрос не обновил строки, это значит, что IP для этого пользователя отсутствует в таблице, поэтому он вставляет его.
$site->query('UPDATE `user_ips` SET `last_time` = UNIX_TIMESTAMP(), `user_agent` = \''.$this->user_agent.'\' WHERE `ip` = '.$this->ip.' AND `userid` = '.$this->id); if(mysql_affected_rows() == 0) { $site->query('INSERT INTO `user_ips` SET `userid` = '.$this->id.', `ip` = '.$this->ip.', `first_time` = UNIX_TIMESTAMP(), `last_time` = UNIX_TIMESTAMP(), `user_agent` = \''.$this->user_agent.'\''); }
Проблема заключается в том, что mysql_affected_rows () иногда возвращает 0, даже если существует строка с текущим идентификатором и IP-адресом пользователя. Таким образом, код добавляет еще одну строку в таблицу с тем же IP-адресом.
В случае, если вам интересно, $ site – это класс mysql, который я сделал для моего сайта, и единственным запросом, который он выполняет, является тот, который он передал с помощью query (), и ничего больше, так что это не проблема с классом. Ох, и IP хранится как длинный IP-адрес, поэтому ему не нужны кавычки.
Я прямо цитирую PHP-документацию здесь:
При использовании UPDATE MySQL не будет обновлять столбцы, где новое значение совпадает со старым значением. Это создает вероятность того, что mysql_affected_rows () может фактически не равняться количеству согласованных строк, а только количеству строк, которые были буквально затронуты запросом.
Поэтому в вашем случае mysql_affected_rows () вернет 0, когда UNIX_TIMESTAMP () возвращает одно и то же значение (например, два запроса от одного и того же клиента за одну секунду).
Чтобы построить ответ slipbull, самым простым способом справиться с этим является, возможно, просто выполнить запрос SELECT для оценки того, нужен ли INSERT. Другим решением было бы просто ВСТАВИТЬ запись при создании пользователя, так как это гарантировало бы действительную запись.
Вы можете просто установить свой первичный ключ для охвата как userid, так и ip. Это гарантирует, что вы не получите дубликатов записей, но вам придется подавить ошибку в запросе вставки, если вы не собираетесь добавлять выбор для проверки записи.
Другим вариантом может быть использование команды MySQL REPLACE. http://dev.mysql.com/doc/refman/5.0/en/replace.html . Которая удалит строку, если она уже существует, а затем вставьте строку.
Хотя это может оказаться неприемлемым для ваших конкретных потребностей.