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()กลับมาเป็นจริงกับความสำเร็จ นอกจากนี้ยังมีPDOStatement->errorCode()ที่คุณสามารถตรวจสอบข้อผิดพลาด


1
คุณดูค่า execute () อย่างไร?
Mallow

29
ไม่มีแบบนี้อีกแล้ว $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
Ólafur Waage

23
หรือคุณสามารถทำได้if ($stmt->execute()) { //true }
Gavin

2
เป็นPDOStatement->execute()และPDOStatement->errorCode()สอดคล้องกันโดยสิ้นเชิงกับแต่ละอื่น ๆ ? มีสถานการณ์ใดบ้างที่PDOStatement->errorCode()มีบางอย่าง แต่PDOStatement->execute()กลับเป็นจริง? หรือเมื่อPDOStatement->execute()คืนค่าเท็จ แต่PDOStatement->errorCode()ไม่มีอะไร?
datasn.io

2
แต่ INSERT IGNORE จะกลับมาเป็นจริงแม้ว่าจะไม่มีการใส่บันทึกใหม่
ก็ตาม

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 มันค่อนข้างเหมือนกัน
สามัญสำนึกของคุณ

คุณพูดถูก .. คุณช่วยบอกฉันเกี่ยวกับquery()ฟังก์ชันได้ไหม? ฉันสามารถใช้ try-catch query()แทนได้prepared()->execute()หรือไม่
Martin 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

คุณสามารถทดสอบ rowcount

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

การอ้างอิงกลับไปยังเอกสารมีประโยชน์เสมอ @YourCommonSense ข้อความระบุว่า "ไม่รับประกันพฤติกรรมนี้สำหรับฐานข้อมูลทั้งหมดและไม่ควรใช้กับแอปพลิเคชันแบบพกพา" แต่ถูก จำกัด ให้เลือกในประการแรกและสนับสนุนประการที่สองสำหรับ mysql ซึ่งเป็นหัวข้อของโพสต์นี้
crafter

เพียงพิมพ์ "pdo rowcount" ในแถบที่อยู่ของเบราว์เซอร์ของคุณแล้วคลิกลิงก์แรก ใช้เวลาพิมพ์น้อยกว่าความคิดเห็น
สามัญสำนึกของคุณ

1
@crafter ถูกต้อง. มันบอกว่า rowCount () ไม่สามารถใช้งานได้สำหรับการSELECTสืบค้น (และถึงแม้ในนั้นเอกสารจะพูดเกี่ยวกับการสืบค้นหลายรายการ ) มันบอกอะไรเกี่ยวกับDELETE, INSERTหรือUPDATEซึ่งดูเหมือนจะดีในการทำงาน (คำถามคือเกี่ยวกับINSERTแบบสอบถาม) อย่างไรก็ตามฉันยังใหม่กับ PDO และหากฉันผิดและมีใครมีข้อมูลอ้างอิงอื่นโปรดเขียนที่นี่ ฉันสนใจที่จะดูว่ามีข้อเสียจริงสำหรับ 3 คำสั่งข้างต้นหรือไม่
StanE

1

ใช้ id เป็นคีย์หลักพร้อมการเพิ่มอัตโนมัติ

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

รหัสที่เพิ่มขึ้นจะใหญ่กว่าศูนย์เสมอแม้ในระเบียนแรกดังนั้นจึงหมายความว่าจะส่งคืนค่าที่แท้จริงสำหรับ id coz ที่ใหญ่กว่าศูนย์หมายถึงจริงใน PHP

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

จะเกิดอะไรขึ้นถ้าฉันไม่ต้องการช่องเพิ่มอัตโนมัติในตารางของฉัน
สามัญสำนึกของคุณ

ใครดัน? คุณ? ด้วย RESTFul API ที่ใช้กันอย่างแพร่หลายดังนั้นรหัสการเพิ่มอัตโนมัติจึงเป็นเหมือนภาคบังคับ
jumper 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.