mysql_affected_rows(); не работает для проверки существования строки

я использую mysql_affected_rows(), чтобы проверить, нужно ли мне вводить новую запись или обновлять существующую, но проблема в том, что пользователь пытается ввести точно такие же данные, как уже существующая запись, в которую он запускает вставку.

$result = mysql_query("update Data set Score='$score',Comment='$_POST[Comments]' where Date='$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]' AND User='$_POST[UserID]';");
$last = mysql_affected_rows();

if ($last==0) {

    $result1 = mysql_query("INSERT INTO Data (User,Date,Score,Comment) VALUES ('$_POST[UserID]','$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]','$score','$_POST[Comments]')");

что мне делать, чтобы избежать лишних записей


person PUG    schedule 05.09.2011    source источник
comment
Пожалуйста, немедленно прочитайте об инъекциях SQL.   -  person Oliver Charlesworth    schedule 05.09.2011
comment
ценю это, но я только пытаюсь сначала сделать функциональную часть.   -  person PUG    schedule 05.09.2011
comment
Просто предложение, но я бы начал изучать PDO. php.net/pdo   -  person Bailey Parker    schedule 05.09.2011


Ответы (3)


  1. Вы можете проанализировать вывод mysql_info() (но само решение будет зависеть от проблемы состояния гонки)
  2. Вы можете создать уникальный ключ User + Date и получить один запрос, используя ON DUPLICATE KEY UPDATE:

    INSERT INTO `Data` (User,Date,Score,Comment)
    ('$_POST[UserID]','$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]','$score','$_POST[Comments]')
    ON DUPLICATE KEY UPDATE Score='$score',Comment='$_POST[Comments]'
    
person zerkms    schedule 05.09.2011
comment
Метод ON DUPLICATE KEY UPDATE показался проще и отлично работает! - person PUG; 05.09.2011

некоторые решения:

  1. добавьте еще один запрос, чтобы увидеть, существуют ли данные, а затем решите, хотите ли вы выполнить какое-либо действие (обновить/удалить) или ничего не делать.
  2. добавить «модифицированный» столбец с типом «TIMESTAMP» и сделать его при обновлении — CURRENT_TIMESTAMP

я бы пошел с первым вариантом.

Кстати, вы должны избегать ваших данных сообщения (mysql_real_escape_string), чтобы предотвратить инъекции или искаженную строку запроса.

person galchen    schedule 05.09.2011
comment
1. Это может вызвать состояние гонки, если OP не позаботится о транзакциях и блокировках. 2. Существуют системы, в которых запрос может прийти в течение одной секунды (таким образом, будет иметь одинаковую метку времени) - person zerkms; 05.09.2011
comment
1. в php проблем быть не должно. 2. тогда используйте миллисекунды - person galchen; 05.09.2011

Вы можете получить количество затронутых строк с помощью FOUND_ROWS() вместо mysql_affected_rows(). Последний также подсчитывает неизмененные строки.

$result = mysql_query("update Data set Score='$score',Comment='$_POST[Comments]' where Date='$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]' AND User='$_POST[UserID]';");
$last = mysql_query("SELECT ROW_COUNT();");
$last = mysql_fetch_array($last);
...

Ссылка: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count

person etuardu    schedule 05.09.2011