PDO mysql: Eklemenin başarılı olup olmadığını nasıl anlarım?


96

Kayıt eklemek için PDO kullanıyorum (mysql ve php)

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

Başarıyla eklenip eklenmediğini bilmenin bir yolu var mı, örneğin kayıt bir kopya olduğu için eklenmemiş mi?

Düzenleme: Tabi ki veritabanına bakabilirim, ancak programlı geribildirimi kastediyorum.

Yanıtlar:


141

PDOStatement->execute()başarı durumunda true döner. PDOStatement->errorCode()Hataları kontrol edebileceğiniz de var.


1
Execute () değerine nasıl bakarsınız?
Ebegümeci

29
Artık böyle değil, $ değer = $ stmt-> execute (); if ($ değer) {// true} else {// false}
Ólafur'dan Feragat

23
Ya da sadece yapabilirsinif ($stmt->execute()) { //true }
Gavin

2
PDOStatement->execute()ve PDOStatement->errorCode()birbirleriyle tamamen tutarlı? Bir PDOStatement->errorCode()şeye sahip olmakla birlikte PDOStatement->execute()gerçeğe döndüğü durumlar var mı ? Ya da PDOStatement->execute()yanlış döndürdüğünde ancak PDOStatement->errorCode()hiçbir şey olmadığında?
datasn.io

2
Ancak INSERT IGNORE, yeni kayıt eklenmemiş olsa bile doğru olarak geri dönecektir
Koffeehaus

26

PDO için en çok önerilen hata modu olduğu göz önüne alındığında ERRMODE_EXCEPTION, hiçbir doğrudan execute()sonuç doğrulaması hiçbir zaman çalışmayacaktır . Kod yürütme, diğer yanıtlarda sunulan koşula bile ulaşmayacağından.

Dolayısıyla, PDO'da sorgu yürütme sonucunu işlemek için üç olası senaryo vardır:

  1. Başarıyı söylemek için hiçbir doğrulamaya gerek yoktur. Sadece program akışınıza uyun.
  2. Beklenmeyen hatayı gidermek için, aynı şekilde devam edin - acil işlem kodu gerekmez. Bir veritabanı hatası durumunda bir istisna atılır ve sonunda ortak bir 500 hata sayfasıyla sonuçlanacak olan site genelindeki hata işleyiciye yükselir.
  3. Yinelenen birincil anahtar gibi beklenen hatayı işlemek için ve bu belirli hatayı işleyecek belirli bir senaryonuz varsa, bir try..catchoperatör kullanın .

Sıradan bir PHP kullanıcısı için kulağa biraz yabancı geliyor - bu nasıl, işlemin doğrudan sonucunu doğrulamak için değil? - ancak istisnalar tam olarak bu şekilde çalışır - hatayı başka bir yerde kontrol edersiniz. Her şey için bir kez. Son derece kullanışlı.

Yani, kısaca: normal bir kodda herhangi bir hata işlemeye ihtiyacınız yoktur. Kodunuzu olduğu gibi saklamanız yeterlidir:

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

Başarı durumunda size bunu söyleyecektir, hata durumunda size uygulamanızın böyle bir durum için gösterdiği normal hata sayfasını gösterecektir.

Sadece hatayı bildirmekten başka bir işleme senaryonuz varsa , insert ifadenizi bir try..catchoperatöre koyun, beklediğiniz hata olup olmadığını kontrol edin ve düzeltin; veya - hata herhangi bir farklıysa - site genelindeki hata işleyicisi tarafından olağan şekilde ele alınmasını mümkün kılmak için istisnayı yeniden fırlatın . Aşağıda PDO ile hata işleme hakkındaki makalemdeki örnek kod bulunmaktadır :

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!";

Yukarıdaki kodda, belirli bir hatayı bir işlem yapmak için kontrol ediyor ve bir programcıya rapor edilecek diğer herhangi bir hata için (örneğin böyle bir tablo yok) istisnayı yeniden fırlatıyoruz.

Yine de - bir kullanıcıya "Ekiniz başarılı" gibi bir şey söylemek için hiçbir koşul gerekmez.


"Başarı" nın anlamı nedir? Bu yeni bir satırın eklendiği anlamına mı geliyor yoksa bu herhangi bir hata olmadığı anlamına mı geliyor?
Martin AJ

INSERT sorgusu için hemen hemen aynıdır.
Ortak

Haklısın .. Lütfen bana query()fonksiyon hakkında ne olduğunu söyleyebilir misin ? query()Bunun yerine try-catch kullanabilir miyim prepared()->execute()?
Martin AJ

3
İlk etapta eklemeler için asla query () kullanmamalısın. Ekleme, giriş olduğu anlamına gelir ve giriş, hazırlanması gerektiği anlamına gelir.
Sağduyu

1
MySQL kullanarak, eklemenin başarısız olduğunu doğrulamak için $ e-> errorInfo [1] == 1062 olup olmadığını kontrol etmeliydim, çünkü $ e-> getCode () her zaman 23000'dir.
tronman


9

Bir güncelleme sorgusu, geçerli veritabanı kaydıyla eşleşen değerlerle yürütülürse, etkilenen satır olmaması için $stmt->rowCount()dönecektir 0. if( rowCount() == 1 )Başarı için test etmeniz gereken bir şey varsa, başarısız olmadığında güncellemenin başarısız olduğunu düşüneceksiniz, ancak değerler zaten veritabanındaydı, dolayısıyla hiçbir şey değişmiyor.

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

İhlal edilen benzersiz bir anahtar alanına sahip bir kaydı güncellemeye çalıştığımda bu benim için işe yaramadı. Sorgu başarılı oldu, ancak başka bir sorgu eski alan değerini döndürüyor.


3
Kaydın eklenmesine İHTİYACINIZ VARSA, en iyi yol bu şekilde kontrol etmektir ............................. ..... .................. if($stmt->execute() && ($stmt->rowCount()>0))
jave.web

4

Satır sayısını test edebilirsiniz

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

Belgelere bir referans @ YourCommonSense her zaman yardımcı olur. "Bu davranış tüm veritabanları için garanti edilmez ve taşınabilir uygulamalar için güvenilmemelidir." Diyor, ancak ilk olarak seçimle sınırlı ve ikinci olarak bu yazının konusu olan mysql için destekleniyor.
crafter

tarayıcınızın adres çubuğuna "pdo rowcount" yazın ve ilk bağlantıyı tıklayın. yorum yazmaktan daha az zaman alır
Your Common Sense

1
@crafter Doğru. RowCount () 'un SELECTsorgular için güvenilmez olabileceğini söylüyor (ve orada bile, dokümanlar birden çok sorudan bahsediyor ). Bu konuda hiçbir şey söylüyor DELETE, INSERTya UPDATE(soru bir hakkındaydı işe iyi olacak gibi görünüyor, INSERTsorgunun). Ancak, PDO'da yeniyim ve yanılıyorsam ve birinin başka referansları varsa, lütfen bunları buraya yazın. Yukarıdaki 3 komutun gerçek dezavantajları olup olmadığını merak ediyorum.
StanE

1

Kimliği otomatik artırmalı birincil anahtar olarak kullan

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

artımlı id, ilk kayıtta bile her zaman sıfırdan büyüktür, bu nedenle her zaman id için gerçek bir değer döndürür coz sıfırdan büyük, PHP'de doğru anlamına gelir

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

Ya tablomda otomatik olarak artan bir alana ihtiyacım yoksa?
Ortak

Kim dun? sen? çok yaygın olarak kullanılan RESTFul API ile otomatik artış kimliği zorunlu gibidir.
jumper rbk

Neden birisi birincil ve otomatik artışa veya başka bir sıra sütununa sahip olmasın? Doğrulama yöntemi gerekiyorsa, herhangi bir sıralı sütun ekleyin. Bu çözüm sizin için değilse onu eklemeyin. Bu benim için iyi bir şey, her zaman bazı sıralı ve otomatik artış sütunları kullanıyorum, bu nedenle sorgumun başarılı olup olmadığını test etmek için her zaman bir yolum var.
Samuel Ramzan

0

PDOStatement-> execute () bir istisna atabilir

yani ne yapabilirsin

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.