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()成功するとtrueを返します。PDOStatement->errorCode()エラーをチェックできるものもあります。


1
execute()値をどのように見ますか?
Mallow

29
これ以上はありません、$ value = $ stmt-> execute(); ($値)であれば{//真}他{//偽}
オラフルWaage

23
または、ただ行うことができますif ($stmt->execute()) { //true }
Gavin

2
であるPDOStatement->execute()PDOStatement->errorCode()お互いに全く一貫?PDOStatement->errorCode()何かがあるPDOStatement->execute()がtrueを返す状況はありますか?またはPDOStatement->execute()falseが返されPDOStatement->errorCode()ても何もない場合は?
datasn.io 2015年

1
しかし、INSERT IGNOREは、新しいレコードが挿入されなかった場合でもtrueを返します
Koffeehaus

24

PDOの最も推奨されるエラーモードはERRMODE_EXCEPTIONであるため、直接的なexecute()結果検証は機能しません。コードの実行は、他の回答で提供された条件にさえ到達しないためです。

したがって、PDOでクエリ実行結果を処理するには、次の3つのシナリオが考えられます。

  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 2016

INSERTクエリの場合も、ほとんど同じです。
常識

あなたは正しいです.. query()機能についてはどうですか?query()代わりにtry-catchを使用できますprepared()->execute()か?
マーティンAJ 2016

3
そもそも、挿入にはquery()を使用しないでください。挿入は入力があることを意味し、入力は準備が必要であることを意味します。
常識

1
MySQLを使用して、私は$ E->のerrorInfo [1] == 1062は、挿入が失敗したことを確認した場合$ E->にgetCode()は常に23000ですので、チェックしなければならなかった
tronmanは


9

現在のデータベースレコードと一致する値で更新クエリを実行すると、影響を受けた行がないため$stmt->rowCount()に戻ります0if( 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クエリにとって信頼できない可能性があることを示しています(そこでも、ドキュメントは複数のクエリについて話します)。動作について問題ないように見えるDELETEINSERTまたはについては何も述べられていませんUPDATE(質問はINSERTクエリ)。ただし、私はPDOを初めて使用するので、私が間違っていて、誰かが別の参照を持っている場合は、ここに書いてください。上記の3つのコマンドに実際の欠点があるかどうかを確認します。
StanE 2017

1

自動インクリメントでIDを主キーとして使用する

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

最初のレコードでもインクリメンタルIDは常にゼロよりも大きいので、ゼロより大きいID cozに対して常に真の値を返します。

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

テーブルに自動インクリメントフィールドが必要ない場合はどうなりますか?
常識

誰だ?君は?広く使用されているRESTFul APIでは、自動インクリメントIDは必須のようです。
ジャンパーrbk

なぜ誰かがプライマリおよび自動インクリメントまたは他のシーケンス列を持っていないのですか?検証方法が必要な場合は、順次列を追加します。このソリューションがない場合は、追加しないでください。それは私にとっては素晴らしいことです。私は常にいくつかの順次および自動インクリメント列を使用するので、クエリが成功したかどうかを常にテストする方法があります。
Samuel Ramzan

0

PDOStatement-> execute()が例外をスローする可能性がある

だからあなたにできることは

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.