Могу ли я обнаруживать и обрабатывать предупреждения MySQL с помощью PHP?

Я имею дело с таблицей MySQL, которая определяет столбец JobName как UNIQUE. Если кто-то пытается сохранить новое задание в базе данных с использованием JobName, которое уже находится в базе данных, MySQL выдает предупреждение.

Я хотел бы иметь возможность обнаружить это предупреждение, точно так же как и ошибку, в моем PHP script и справиться с ним соответствующим образом. В идеале я хотел бы знать, какое предупреждение вышло MySQL, чтобы я мог обработать код для его обработки.

Возможно ли это? Если нет, это потому, что MySQL не обладает этой способностью, PHP не обладает этой способностью или оба?

Ответ 1

Для предупреждений, которые должны быть "помечены" для PHP, изначально потребовались бы изменения в драйвере mysql/mysqli, что явно выходит за рамки этого вопроса. Вместо этого вам придется в основном проверить каждый запрос, который вы делаете в базе данных, для предупреждений:

$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
    $warningCount = mysql_fetch_row($warningCountResult );
    if ($warningCount[0] > 0) {
        //Have warnings
        $warningDetailResult = mysql_query("SHOW WARNINGS");
        if ($warningDetailResult ) {
            while ($warning = mysql_fetch_assoc(warningDetailResult) {
                //Process it
            }
        }
    }//Else no warnings
}

Очевидно, что это будет ужасно дорого для применения en-mass, поэтому вам может потребоваться тщательно подумать о том, когда и как могут возникнуть предупреждения (что может привести к рефактору для их устранения).

Для справки MySQL SHOW WARNINGS

Конечно, вы можете обойтись без первоначального запроса для SELECT @@warning_count, который сохранит вам запрос за выполнение, но я включил его для полноты педантичности.

Ответ 2

Во-первых, вы должны отключить предупреждения, чтобы ваши посетители не видели ваши ошибки MySQL. Во-вторых, когда вы вызываете mysql_query(), вы должны проверить, вернули ли он false. Если это так, позвоните mysql_errno(), чтобы узнать, что пошло не так. Сопоставьте номер, возвращенный кодам ошибок на этой странице.

Похоже, это номер ошибки, которую вы ищете:

Ошибка: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)

Сообщение: не удается записать из-за уникального ограничения в таблицу '% s'

Ответ 3

ini_set('mysql.trace_mode', 1)

может быть тем, что вы ищете.

Затем ошибки PHP могут обрабатываться с помощью специального обработчика ошибок PHP, но вы также можете просто отключить отображение ошибок php, поскольку они обычно регистрируются в файле журнала (зависит от вашей конфигурации php).

Ответ 4

Обновлено для удаления информации о функциях errno, которые я теперь понимаю, не применяются в вашей ситуации...

Одна вещь в MySQL, которую следует опасаться для операторов UPDATE: mysqli_affected_rows() будет возвращать ноль, даже если соответствующие строки WHERE соответствуют строкам, но предложение SET фактически не изменило значения данных. Я упоминаю об этом только потому, что это поведение вызвало ошибку в системе, которую я когда-то смотрел - программист использовал это возвращаемое значение для проверки ошибок после обновления, предполагая, что нуль означает, что произошла какая-то ошибка. Это просто означало, что пользователь не изменял никаких существующих значений перед нажатием кнопки обновления.

Таким образом, я полагаю, что использование mysqli_affected_rows() не может быть использовано для поиска таких предупреждений, если только у вас есть что-то вроде столбца update_time в вашей таблице, которому при обновлении всегда будет назначаться новое значение метки времени. Однако такое обходное решение кажется любезным kludgey.

Ответ 5

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

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

Если это не имеет смысла для вас, то суммируйте мой взгляд на это: не создавайте свою программу и/или пользователей, чтобы пытаться делать нелегальные вещи и ловить ошибки, когда они это делают и обрабатывают. Намного лучше, imho, создать вашу систему, чтобы не создавать ошибок. Храните ошибки в действительных ошибках:)

Ответ 6

Вы можете обнаружить уникальные нарушения ключей с помощью ошибки mysqli no. Оператор mysqli возвращает ошибку 1062, то есть ER_DUP_ENTRY. Вы можете найти ошибку 1062 и напечатать подходящее сообщение об ошибке. Если вы хотите напечатать свой столбец (имя_пользователя) также как часть вашего сообщения об ошибке, вы должны проанализировать строку ошибки оператора.

  if($stmt = $mysqli->prepare($sql)){
            $stmt->bind_param("sss",
            $name,
            $identKey,
            $domain);


            $stmt->execute();
            if($mysqli->affected_rows != 1)  {
                        //This will return errorno 1062
                trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR);
                exit(1);
            }
            $stmt->close();
        } else {

            trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR);
        }

Ответ 7

Можно получить предупреждения и более эффективно с помощью mysqli, чем с mysql.

Вот код, предложенный в руководстве страница на php.net для свойства mysqli- > warning_count:

$mysqli->query($query);

if ($mysqli->warning_count) {
    if ($result = $mysqli->query("SHOW WARNINGS")) {
        $row = $result->fetch_row();
        printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
        $result->close();
    }
}

Ответ 8

Примечание по подавлению предупреждений: Как правило, не рекомендуется предотвращать отображение предупреждений, так как вы можете пропустить что-то важное. Если вы по какой-то причине обязательно должны скрывать предупреждения, вы можете сделать это индивидуально, поставив перед тегом знак @. Таким образом, вам не нужно отключать все предупреждения и ограничивать их конкретным экземпляром.

Пример:

 // this suppresses warnings that might result if there is no field titled "field" in the result
 $field_value = @mysql_result($result, 0, "field");