PDO mysql: Як дізнатись, чи вставка була успішною


96

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

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

Чи є спосіб дізнатись, чи вдалося його вставити, наприклад, якщо запис не був вставлений, оскільки він був дублікатом?

Редагувати: звичайно, я можу подивитися базу даних, але я маю на увазі програмний зворотний зв'язок.

Відповіді:


140

PDOStatement->execute()повертає істину на успіх. Є також PDOStatement->errorCode()який ви можете перевірити на наявність помилок.


1
Як ви дивитесь на значення execute ()?
Mallow

29
Більше такого, $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
flafur Waage

23
Або ви можете просто зробитиif ($stmt->execute()) { //true }
Гевін

2
Чи узгоджуються PDOStatement->execute()та PDOStatement->errorCode()повністю узгоджуються між собою? Чи існують обставини, коли PDOStatement->errorCode()щось має, але PDOStatement->execute()повертається істиною? Або коли PDOStatement->execute()повертає false, але PDOStatement->errorCode()нічого не має?
datasn.io

1
Але INSERT IGNORE також повернеться правдою, навіть якщо не буде вставлено новий запис
Koffeehaus

24

Зважаючи на те, що найбільш рекомендований режим помилок для 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 це майже те саме.
Твій здоровий глузд

Ви маєте рацію. Просто скажіть, будь ласка, про query()функцію? Чи можу я використовувати пробний лов query()замість prepared()->execute()?
Мартін AJ

3
Ніколи не слід використовувати query () для вставок в першу чергу. Вставка означає, що є вхід, а вхід означає, що його слід підготувати.
Твій здоровий глузд

1
Використовуючи MySQL, я повинен був перевірити, чи $ e-> errorInfo [1] == 1062, щоб переконатися, що вставка не вдалася, оскільки $ e-> getCode () завжди 23000.
tronman


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, що є предметом цієї публікації.
крафтер

просто введіть "pdo rowcount" в адресному рядку браузера та натисніть перше посилання. потрібно менше набирати текст, ніж коментар
Ваше здорове почуття

1
@crafter Правильно. У ньому йдеться про те, що rowCount () може бути невиправданим для SELECTзапитів (і навіть там документи говорять про кілька запитів). Це нічого не говорить про те DELETE, INSERTабо UPDATE, що, здається, непогано працювати (питання стосувалося INSERTзапиту). Однак я новачок в PDO, і якщо я помиляюся, а хтось має інші посилання, напишіть їх тут. Мені цікаво подивитися, чи є реальні недоліки для 3-х команд, наведених вище.
СТЕН

1

Використовуйте id в якості основного ключа з автоматичним збільшенням

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

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

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

Що робити, якщо мені не потрібне поле з автоматичним збільшенням у моїй таблиці?
Ваш здоровий глузд

Хто дон? ти? за допомогою API RESTFul, який використовується настільки широким ідентифікатором автоматичного збільшення, як обов'язковий.
джемпер 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.