PDO mysql: Bagaimana cara mengetahui apakah penyisipan berhasil

96

Saya menggunakan PDO untuk memasukkan catatan (mysql dan php)

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

Adakah cara untuk mengetahui apakah itu berhasil disisipkan, misalnya jika catatan tidak dimasukkan karena merupakan duplikat?

Sunting: tentu saja saya dapat melihat database, tapi maksud saya umpan balik terprogram.

Chris
sumber

Jawaban:

140

PDOStatement->execute()kembali benar pada kesuksesan. Ada juga PDOStatement->errorCode()yang bisa Anda periksa kesalahannya.

Ólafur Waage
sumber
1
Bagaimana Anda melihat nilai execute ()?
Mallow
29
Tidak ada lagi yang seperti ini, $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
Ólafur Waage
23
Atau Anda bisa melakukannyaif ($stmt->execute()) { //true }
Gavin
2
Apakah PDOStatement->execute()dan PDOStatement->errorCode()sepenuhnya konsisten satu sama lain? Apakah ada keadaan ketika PDOStatement->errorCode()memiliki sesuatu tetapi PDOStatement->execute()kembali benar? Atau ketika PDOStatement->execute()mengembalikan false tetapi PDOStatement->errorCode()tidak memiliki apa-apa?
datasetn.io
1
Tetapi INSERT IGNORE juga akan mengembalikan true meskipun tidak ada rekor baru yang dimasukkan
Koffeehaus
25

Mengingat mode kesalahan yang paling direkomendasikan untuk PDO adalah ERRMODE_EXCEPTION, tidak ada execute()verifikasi hasil langsung yang akan berfungsi . Karena eksekusi kode bahkan tidak akan mencapai kondisi yang ditawarkan di jawaban lain.

Jadi, ada tiga skenario yang mungkin untuk menangani hasil eksekusi query di PDO:

  1. Untuk mengetahui keberhasilannya, tidak diperlukan verifikasi. Tetap ikuti alur program Anda.
  2. Untuk menangani error yang tidak terduga, pertahankan hal yang sama - tidak perlu kode penanganan segera. Pengecualian akan diberikan jika terjadi kesalahan basis data, dan itu akan menggelembung ke penangan kesalahan seluruh situs yang pada akhirnya akan menghasilkan 500 laman kesalahan umum.
  3. Untuk menangani kesalahan yang diharapkan, seperti kunci utama duplikat, dan jika Anda memiliki skenario tertentu untuk menangani kesalahan khusus ini, gunakan try..catchoperator.

Untuk pengguna PHP biasa kedengarannya agak asing - bagaimana, bukan untuk memverifikasi hasil langsung dari operasi? - tetapi beginilah tepatnya cara kerja pengecualian - Anda memeriksa kesalahan di tempat lain. Sekali untuk semua. Sangat nyaman.

Jadi, singkatnya: dalam kode biasa Anda tidak memerlukan penanganan error sama sekali. Simpan saja kode Anda apa adanya:

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

Jika berhasil, ia akan memberi tahu Anda demikian, jika ada kesalahan ia akan menampilkan halaman kesalahan biasa bahwa aplikasi Anda ditampilkan untuk acara seperti itu.

Hanya jika Anda memiliki skenario penanganan selain hanya melaporkan kesalahan, letakkan pernyataan insert Anda di try..catchoperator, periksa apakah itu kesalahan yang Anda harapkan dan menanganinya; atau - jika kesalahannya berbeda - lemparkan kembali pengecualian, untuk memungkinkan penanganan kesalahan di seluruh situs dengan cara biasa. Di bawah ini adalah contoh kode dari artikel saya tentang penanganan kesalahan dengan 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!";

Dalam kode di atas kami memeriksa kesalahan tertentu untuk mengambil beberapa tindakan dan mengembalikan pengecualian untuk kesalahan lainnya (tidak ada tabel seperti itu misalnya) yang akan dilaporkan ke programmer.

Sementara lagi - hanya untuk memberi tahu pengguna sesuatu seperti "Penyisipan Anda berhasil", tidak ada ketentuan yang diperlukan.

Akal Sehat Anda
sumber
Apa artinya "Sukses"? Apakah itu berarti baris baru disisipkan, atau itu berarti tidak ada kesalahan?
Martin AJ
Untuk kueri INSERT kurang lebih sama.
Akal Sehat Anda
Anda benar .. Bolehkah Anda memberi tahu saya bagaimana dengan query()fungsinya? Dapatkah saya menggunakan coba-tangkap untuk query()alih - alih prepared()->execute()?
Martin AJ
3
Anda tidak boleh menggunakan query () untuk menyisipkan di tempat pertama. Sisipkan artinya ada input dan inpout artinya harus disiapkan.
Akal Sehat Anda
1
Menggunakan MySQL, saya harus memeriksa apakah $ e-> errorInfo [1] == 1062 untuk memverifikasi bahwa penyisipan gagal, karena $ e-> getCode () selalu
23000.
9

Coba lihat nilai pengembalian execute, yaitu TRUEpada kesuksesan, dan FALSEpada kegagalan.

Dominic Rodger
sumber
9

Jika kueri pembaruan dijalankan dengan nilai yang cocok dengan catatan database saat ini, maka tidak $stmt->rowCount()akan 0ada baris yang terpengaruh. Jika Anda memiliki if( rowCount() == 1 )untuk menguji keberhasilan, Anda akan mengira pembaruan gagal ketika tidak gagal tetapi nilainya sudah ada di database jadi tidak ada yang berubah.

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

Ini tidak berhasil untuk saya ketika saya mencoba memperbarui rekaman dengan bidang kunci unik yang dilanggar. Kueri kembali berhasil tetapi kueri lain mengembalikan nilai bidang lama.

dan
sumber
3
Jika Anda MEMBUTUHKAN record untuk dimasukkan, cara terbaik adalah dengan memeriksa seperti ini ............................. ..... .................. if($stmt->execute() && ($stmt->rowCount()>0))
jave.web
4

Anda dapat menguji rowcount

    $sqlStatement->execute( ...);
    if ($sqlStatement->rowCount() > 0)
    {
        return true;
    }
perajin
sumber
Referensi kembali ke dokumen selalu membantu @YourCommonSense. Dikatakan "perilaku ini tidak dijamin untuk semua database dan tidak boleh diandalkan untuk aplikasi portabel." Tetapi dibatasi untuk memilih pertama, dan kedua didukung untuk mysql, yang merupakan subjek posting ini.
perajin
cukup ketik "pdo rowcount" di bilah alamat browser Anda dan klik tautan pertama. dibutuhkan lebih sedikit mengetik daripada komentar
Akal Sehat Anda
1
@crafter Benar. Dikatakan bahwa rowCount () tidak dapat dihubungkan untuk SELECTkueri (dan bahkan di sana, dokumen berbicara tentang beberapa kueri). Ia tidak mengatakan apa-apa tentang DELETE, INSERTatau UPDATE, yang tampaknya baik-baik saja untuk bekerja (pertanyaannya adalah tentang INSERTkueri). Namun, saya baru mengenal PDO dan jika saya salah dan seseorang memiliki referensi lain, silakan tulis di sini. Saya tertarik untuk melihat apakah ada kerugian nyata untuk 3 perintah di atas.
StanE
1

Gunakan id sebagai kunci utama dengan penambahan otomatis

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

incremental id selalu lebih besar dari nol bahkan pada record pertama sehingga itu berarti akan selalu mengembalikan nilai sebenarnya untuk id karena lebih besar dari nol berarti benar dalam PHP

if ($insertid)
   echo "record inserted successfully";
else
   echo "record insertion failed";
pelompat rbk
sumber
Bagaimana jika saya tidak membutuhkan bidang yang bertambah otomatis di tabel saya?
Akal Sehat Anda
Siapa yang melakukannya? kamu? dengan RESTFul API yang digunakan secara luas, auto increment id seperti wajib.
jumper rbk
Mengapa seseorang tidak memiliki penambahan primer dan otomatis atau kolom urutan lainnya? Jika metode verifikasi diperlukan, tambahkan kolom berurutan apa pun. Jika solusi ini bukan untuk Anda, jangan tambahkan. Itu bagus bagi saya, saya selalu menggunakan beberapa kolom berurutan dan kenaikan otomatis, jadi saya selalu punya cara untuk menguji apakah kueri saya berhasil.
Samuel Ramzan
0

PDOStatement-> execute () dapat memunculkan pengecualian

jadi yang bisa kamu lakukan adalah

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
Sumit P Makwana
sumber