PDO mysql: Làm thế nào để biết liệu chèn thành công


96

Tôi đang sử dụng PDO để chèn bản ghi (mysql và php)

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

Có cách nào để biết nếu nó được chèn thành công, chẳng hạn như nếu bản ghi không được chèn vì nó là bản sao?

Chỉnh sửa: tất nhiên tôi có thể xem cơ sở dữ liệu, nhưng ý tôi là phản hồi có lập trình.

Câu trả lời:


140

PDOStatement->execute()trả về true trên thành công. Ngoài ra PDOStatement->errorCode(), bạn có thể kiểm tra lỗi.


1
Bạn nhìn vào giá trị execute () như thế nào?
Mallow

29
Không còn như thế này nữa, $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
Ólafur Waage

23
Hoặc bạn chỉ có thể làmif ($stmt->execute()) { //true }
Gavin

2
PDOStatement->execute()PDOStatement->errorCode()hoàn toàn phù hợp với nhau không? Có trường hợp nào khi PDOStatement->errorCode()có cái gì đó nhưng PDOStatement->execute()trả về true không? Hoặc khi PDOStatement->execute()trả về false nhưng PDOStatement->errorCode()không có gì?
datasn.io

1
Nhưng INSERT bỏ qua cũng sẽ quay trở lại đúng ngay cả khi không có hồ sơ mới được chèn
Koffeehaus

24

Do chế độ lỗi được đề xuất nhiều nhất cho PDO ERRMODE_EXCEPTION, không có execute()xác minh kết quả trực tiếp nào hoạt động . Vì việc thực thi mã thậm chí sẽ không đạt được điều kiện được cung cấp trong các câu trả lời khác.

Vì vậy, có ba trường hợp có thể xảy ra để xử lý kết quả thực thi truy vấn trong PDO:

  1. Để cho biết thành công, không cần xác minh. Chỉ cần tuân theo quy trình chương trình của bạn.
  2. Để xử lý lỗi không mong muốn, hãy giữ nguyên tương tự - không cần mã xử lý ngay lập tức. Một ngoại lệ sẽ được đưa ra trong trường hợp có lỗi cơ sở dữ liệu và nó sẽ xuất hiện trong trình xử lý lỗi trên toàn trang web và cuối cùng sẽ dẫn đến một trang lỗi chung 500.
  3. Để xử lý lỗi mong đợi, chẳng hạn như khóa chính trùng lặp và nếu bạn có một tình huống nào đó để xử lý lỗi cụ thể này, hãy sử dụng try..catchtoán tử.

Đối với một người dùng PHP thông thường, nó có vẻ hơi xa lạ - thế này, không phải để xác minh kết quả trực tiếp của thao tác? - nhưng đây chính xác là cách hoạt động của các ngoại lệ - bạn kiểm tra lỗi ở một nơi khác. Một lần cho tất cả. Tiện lợi vô cùng.

Vì vậy, tóm lại: trong một mã thông thường, bạn không cần phải xử lý lỗi nào cả. Chỉ cần giữ nguyên mã của bạn:

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

Khi thành công, nó sẽ cho bạn biết như vậy, nếu có lỗi, nó sẽ hiển thị cho bạn trang lỗi thường xuyên mà ứng dụng của bạn đang hiển thị cho một trường hợp như vậy.

Chỉ trong trường hợp bạn có một tình huống xử lý khác ngoài việc báo cáo lỗi, hãy đặt câu lệnh chèn của bạn vào một try..catchtoán tử, kiểm tra xem đó có phải là lỗi bạn mong đợi hay không và xử lý nó; hoặc - nếu lỗi là bất kỳ khác nào - hãy ném lại ngoại lệ, để trình xử lý lỗi trên toàn trang có thể xử lý theo cách thông thường. Dưới đây là mã ví dụ từ bài viết của tôi về xử lý lỗi với 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!";

Trong đoạn mã trên, chúng tôi đang kiểm tra lỗi cụ thể để thực hiện một số hành động và ném lại ngoại lệ cho bất kỳ lỗi nào khác (không có bảng nào như vậy chẳng hạn) sẽ được báo cáo cho lập trình viên.

Trong khi một lần nữa - chỉ để nói với người dùng điều gì đó như "Chèn của bạn đã thành công" thì không cần điều kiện nào.


Ý nghĩa của "Thành công" là gì? Điều đó có nghĩa là một hàng mới được chèn vào, hay điều đó có nghĩa là không có bất kỳ lỗi nào?
Martin AJ

Đối với truy vấn INSERT, nó khá giống nhau.
Your Common Sense

Bạn đúng .. Chỉ cần bạn vui lòng cho tôi biết những gì về query()chức năng? Tôi có thể sử dụng try-catch query()thay vì prepared()->execute()không?
Martin AJ

3
Bạn không bao giờ nên sử dụng truy vấn () để chèn ngay từ đầu. Chèn nghĩa là có đầu vào và đầu vào có nghĩa là nó phải được chuẩn bị.
Your Common Sense

1
Sử dụng MySQL, tôi đã phải kiểm tra xem $ e-> errorInfo [1] == 1062 để xác minh rằng chèn thất bại, vì $ e-> getCode () luôn luôn là 23000.
tronman


9

Nếu truy vấn cập nhật thực thi với các giá trị phù hợp với bản ghi cơ sở dữ liệu hiện tại thì $stmt->rowCount()sẽ trả về 0không có hàng nào bị ảnh hưởng. Nếu bạn phải if( rowCount() == 1 )kiểm tra thành công, bạn sẽ nghĩ rằng cập nhật không thành công khi nó không bị lỗi nhưng các giá trị đã có trong cơ sở dữ liệu nên không có gì thay đổi.

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

Điều này không hiệu quả đối với tôi khi tôi cố gắng cập nhật bản ghi có trường khóa duy nhất bị vi phạm. Truy vấn trả về thành công nhưng một truy vấn khác trả về giá trị trường cũ.


3
Nếu bạn CẦN chèn bản ghi, cách tốt nhất là kiểm tra như thế này ............................. .................. if($stmt->execute() && ($stmt->rowCount()>0))
jave.web

4

Bạn có thể kiểm tra số lượng hàng

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

Tham chiếu lại tài liệu luôn hữu ích @YourCommonSense. Nó nói rằng "hành vi này không được đảm bảo cho tất cả các cơ sở dữ liệu và không nên dựa vào các ứng dụng di động".
crafter

chỉ cần nhập "pdo rowcount" vào thanh địa chỉ của trình duyệt và nhấp vào liên kết đầu tiên. cần ít nhập hơn một bình luận
của bạn Common Sense

1
@crafter Đúng. Nó nói rằng rowCount () có thể không đáng tin cậy đối với SELECTcác truy vấn (và thậm chí ở đó, các tài liệu nói về nhiều truy vấn). Nó không nói gì về DELETE, INSERThoặc UPDATE, có vẻ như hoạt động tốt (câu hỏi là về một INSERTtruy vấn). Tuy nhiên, tôi mới làm quen với PDO và nếu tôi sai và ai đó có tài liệu tham khảo khác, vui lòng viết chúng ở đây. Tôi quan tâm để xem liệu có bất lợi thực sự cho 3 lệnh trên không.
StanE

1

Sử dụng id làm khóa chính với tăng tự động

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

id tăng dần luôn lớn hơn 0 ngay cả trên bản ghi đầu tiên, điều đó có nghĩa là nó sẽ luôn trả về giá trị true cho id coz lớn hơn 0 có nghĩa là true trong PHP

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

Điều gì sẽ xảy ra nếu tôi không cần trường tăng dần tự động trong bảng của mình?
Your Common Sense,

Ai dun? bạn? với API RESTFul đang được sử dụng rộng rãi nên id tăng dần tự động giống như bắt buộc.
jumper rbk

Tại sao ai đó sẽ không có cột tăng chính và tự động hoặc bất kỳ cột trình tự nào khác? Nếu cần phương pháp xác minh, hãy thêm bất kỳ cột tuần tự nào. Nếu giải pháp này không dành cho Bạn không thêm nó. Đó là một điều tốt đối với tôi, tôi luôn sử dụng một số cột tuần tự và tự động tăng dần, vì vậy tôi luôn có cách để kiểm tra xem truy vấn của mình có thành công hay không.
Samuel Ramzan

0

PDOStatement-> execute () có thể ném một ngoại lệ

vì vậy những gì bạn có thể làm là

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.