PDO mysql: как узнать, прошла ли вставка успешно


96

Я использую PDO для вставки записи (mysql и php)

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();

Есть ли способ узнать, успешно ли он вставлен, например, если запись не была вставлена, потому что это была дубликат?

Изменить: конечно, я могу посмотреть базу данных, но я имею в виду программную обратную связь.

Ответы:


141

PDOStatement->execute()возвращает true в случае успеха. Там также PDOStatement->errorCode()вы можете проверить наличие ошибок.


1
Как вы смотрите на значение execute ()?
— Mallow

29
Больше ничего подобного, $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
— Ólafur Waage

23
Или вы можете просто сделатьif ($stmt->execute()) { //true }
— Гэвин

2
Согласуются ли PDOStatement->execute()и PDOStatement->errorCode()полностью друг с другом? Есть ли обстоятельства, при PDOStatement->errorCode()которых что-то есть, но PDOStatement->execute()возвращает true? Или когда PDOStatement->execute()возвращается false, но PDOStatement->errorCode()ничего не имеет?
— datasn.io

2
Но INSERT IGNORE также вернет истину, даже если новая запись не будет вставлена
— Koffeehaus

26

Учитывая, что наиболее рекомендуемый режим ошибок для PDO - это ERRMODE_EXCEPTION, никакая прямая execute()проверка результатов никогда не будет работать . Поскольку выполнение кода даже не достигнет условия, предложенного в других ответах.

Итак, есть три возможных сценария обработки результата выполнения запроса в PDO:

  1. Чтобы сказать об успехе, проверка не требуется. Просто следите за ходом своей программы.
  2. Чтобы справиться с неожиданной ошибкой, придерживайтесь того же принципа - код немедленной обработки не требуется. В случае ошибки базы данных будет сгенерировано исключение, и оно будет передано обработчику ошибок всего сайта, что в конечном итоге приведет к появлению стандартной страницы с ошибкой 500.
  3. Чтобы обработать ожидаемую ошибку, например дублированный первичный ключ, и если у вас есть определенный сценарий для обработки этой конкретной ошибки, используйте try..catchоператор.

Для обычного пользователя PHP это звучит немного чуждо - как же, чтобы не проверить прямой результат операции? - но именно так работают исключения - вы проверяете ошибку в другом месте. Раз и навсегда. Чрезвычайно удобно.

Итак, в двух словах: в обычном коде обработка ошибок не требуется. Просто сохраните свой код как есть:

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();
echo "Success!"; // whatever

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

Только в случае, если у вас есть сценарий обработки, отличный от простого сообщения об ошибке, поместите оператор вставки в try..catchоператор, проверьте, была ли это ожидаемая вами ошибка, и обработайте ее; или - если ошибка была другой - повторно вызовите исключение, чтобы обработчик ошибок всего сайта мог обработать его обычным способом. Ниже приведен пример кода из моей статьи об обработке ошибок с помощью PDO :

try {
     $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}
echo "Success!";

В приведенном выше коде мы проверяем конкретную ошибку, чтобы предпринять какие-либо действия, и повторно генерируем исключение для любой другой ошибки (например, такой таблицы нет), о которой будет сообщено программисту.

И опять же - просто сказать пользователю что-то вроде «Ваша вставка прошла успешно» никаких условий не требуется.


Что означает «успех»? Означает ли это, что вставлена ​​новая строка, или это означает, что ошибки нет?
— Martin AJ

Для запроса INSERT это почти то же самое.
— Your Common Sense

Вы правы .. Подскажите, пожалуйста, как насчет query()функции? Могу ли я использовать try-catch query()вместо prepared()->execute()?
— Martin AJ

3
Вы никогда не должны использовать query () для вставки в первую очередь. Вставка означает, что ввод есть, а ввод означает, что он должен быть подготовлен.
— Your Common Sense

1
Используя MySQL, мне пришлось проверить, есть ли $ e-> errorInfo [1] == 1062, чтобы убедиться, что вставка не удалась, потому что $ e-> getCode () всегда
— равно 23000.


9

Если запрос на обновление выполняется со значениями, соответствующими текущей записи базы данных, он $stmt->rowCount()вернется, так 0как никакие строки не были затронуты. Если у вас есть if( rowCount() == 1 )проверка на успех, вы подумаете, что обновление завершилось неудачно, если оно не прошло, но значения уже были в базе данных, поэтому ничего не изменится.

$stmt->execute();
if( $stmt ) return "success";

Это не сработало для меня, когда я попытался обновить запись с уникальным ключевым полем, которое было нарушено. Запрос вернул успех, но другой запрос вернул старое значение поля.


3
Если вам НУЖНО вставить запись, лучше всего проверить это так ............................. ..... .................. if($stmt->execute() && ($stmt->rowCount()>0))
— jave.web

4

Вы можете проверить количество строк

    $sqlStatement->execute( ...);
    if ($sqlStatement->rowCount() > 0)
    {
        return true;
    }

Ссылка на документы всегда полезна @YourCommonSense. В нем говорится, что «такое поведение не гарантируется для всех баз данных и на него не следует полагаться для переносимых приложений», но ограничено, во-первых, выбором, а во-вторых, поддерживается для mysql, который является предметом этого сообщения.
— Crafter

просто введите «pdo rowcount» в адресной строке браузера и щелкните первую ссылку. печатать нужно меньше, чем комментарий
— Ваш здравый смысл

1
@crafter Правильно. Он говорит, что rowCount () может быть ненадежным для SELECTзапросов (и даже там в документации говорится о нескольких запросах). Он ничего не говорит о том DELETE, INSERTили UPDATE, которые , кажется , будет хорошо работать (речь шла о INSERTзапросе). Однако я новичок в PDO, и если я ошибаюсь и у кого-то есть другие ссылки, напишите их здесь. Мне интересно узнать, есть ли реальные недостатки у трех приведенных выше команд.
— StanE

1

Использовать идентификатор как первичный ключ с автоматическим приращением

$stmt->execute();
$insertid = $conn->lastInsertId();

инкрементный идентификатор всегда больше нуля даже в первой записи, это означает, что он всегда будет возвращать истинное значение для id coz больше нуля означает истину в PHP

if ($insertid)
   echo "record inserted successfully";
else
   echo "record insertion failed";

Что делать, если мне не нужно автоматически увеличивать поле в моей таблице?
— Your Common Sense

Кто дан? ты? с помощью RESTFul API, который так широко используется, автоматическое увеличение идентификатора похоже на обязательное.
— джемпер rbk

Почему у кого-то нет основного столбца и столбца с автоматическим приращением или любого другого столбца последовательности? Если нужен метод проверки, добавьте любой последовательный столбец. Если это решение не для Вас, не добавляйте его. Для меня это хорошо, я всегда использую столбец с последовательным и автоматическим приращением, поэтому у меня всегда есть способ проверить, был ли мой запрос успешным.
— Самуэль Рамзан

0

PDOStatement-> execute () может вызвать исключение

так что ты можешь сделать это

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.