2011-07-06 20 views
5

Bạn có thể chuẩn bị nhiều số liệu thống kê trước khi thực thi chúng không?Chuẩn bị nhiều số liệu thống kê trước khi thực hiện chúng trong một giao dịch?

$db = PDO('..connection info...'); 
$cats_stmt = $db->prepare('SELECT * FROM cats'); 
$dogs_stmt = $db->prepare('SELECT * FROM dogs'); 

$cats_stmt->execute(); 
$cats = $cats_stmt->fetchAll(PDO::FETCH_CLASS);//list of cats 

$dogs_stmt->execute(); 
$dogs = $dogs_stmt->fetchAll(PDO::FETCH_CLASS);//list of dogs 

Điều này sẽ hữu ích cho các vòng có 2 câu lệnh với các biến khác nhau cần được thực thi sau mỗi lần khác. như thế này:

$stmt_addcat = $db->prepare('INSERT INTO cats (name,age) VALUES(?,?)'); 
$stmt_adddog = $db->prepare('INSERT INTO dogs (name,age) VALUES(?,?)'); 

foreach($cat_n_dog as $bunch){ 
    $db->beginTransaction(); 
    $dog_name = $bunch['dog']['name']; 
    $dog_age = $bunch['dog']['age']; 
    $stmt_adddog->bindParam(1,$dog_name,PDO::PARAM_STR); 
    $stmt_adddog->bindParam(2,$dog_age,PDO::PARAM_STR); 
    $result = $stmt_adddog->execute(); 
    if($result===false){ 
    $db->rollBack(); 
    continue; 
    } 
    $cat_name = $bunch['cat']['name']; 
    $cat_age = $bunch['cat']['age']; 
    $stmt_addcat->bindParam(1,$cat_name,PDO::PARAM_STR); 
    $stmt_addcat->bindParam(2,$cat_age,PDO::PARAM_STR); 
    $result = $stmt_addcat->execute(); 
    if($result===false){ 
    $db->rollBack(); 
    continue; 
    } 
    $db->commit(); 
} 

Tôi hỏi vì tôi đã có những tình huống mà PDO sẽ hành động lỗi và ném lỗi trên tài xế sqlite, vì vậy tôi tự hỏi nếu ví dụ trên thậm chí còn phải làm việc.

p.s. ví dụ được thực hiện tại chỗ.

+0

Tại sao không thử nó? –

+2

Bạn hoàn toàn có thể sử dụng PDO theo cách bạn mô tả. Vấn đề duy nhất là bạn sử dụng 'beginTransaction()' trong câu lệnh 'foreach', đánh bại mục đích của các giao dịch nhưng tôi không biết đó là một sai lầm bạn đã thực hiện trong khi gõ ví dụ này hay là cái gì đó bạn thực sự sử dụng. –

+0

lỗi bài ném bởi trình điều khiển pdo sqlite –

Trả lời

6

Tôi sẽ đăng câu trả lời vì nhận xét không cho phép đủ dung lượng.

Có, bạn có thể chuẩn bị một số câu lệnh chuẩn bị và sau đó thực hiện chúng trong một vòng lặp, không có gì sai với điều đó.

Phần giao dịch không đúng. Nếu bạn muốn thực hiện tất cả hoặc không có truy vấn, bạn cần phải bắt đầu giao dịch của bạn bên ngoài vòng lặp (cùng với cam kết). Đó là nơi mà try/catch của PHP có ích.

$db = PDO('..connection info...'); 

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set error mode to exceptions 

try 
{ 
    $stmt_addcat = $db->prepare('INSERT INTO cats (name,age) VALUES(?,?)'); 
    $stmt_adddog = $db->prepare('INSERT INTO dogs (name,age) VALUES(?,?)'); 

    $db->beginTransaction(); 

    foreach($cat_n_dog as $bunch) { } // Do your foreach binding and executing here 

    $db->commit(); 
} 
catch(PDOException $e) 
{ 
    $db->rollBack(); 

    echo "Error occurred. Error message: ". $e->getMessage() .". File: ". $e->getFile() .". Line: ". $e->getLine(); 
} 
+0

Tôi nghĩ rằng mỗi giao dịch "nhóm" các truy vấn, do đó, bằng cách chèn mỗi cặp chó mèo trong một giao dịch trong vòng lặp sẽ cho phép vòng lặp tiếp tục hoặc không thành công trên một cặp truy vấn. p.s. foreach của bạn có bao gồm rollback không? –

+0

Bạn muốn thực hiện 1 truy vấn mèo và 1 truy vấn con chó theo cách bạn đã xây dựng giao dịch của mình. Điểm giao dịch là tất cả hoặc không, tại sao bạn nhóm chúng 2 x 2? Tôi quên rollback trong ví dụ của tôi, tôi đã chỉnh sửa nó nên nó phải rõ ràng hơn. –

+0

vâng, việc khôi phục trong ví dụ của bạn đã giúp ích, cảm ơn bạn. –

-1

chỉ muốn bình luận ở đây là khi tôi đặt mã được cung cấp bởi Michael J.V. vào dự án của tôi, tôi đã có một nụ cười trên khuôn mặt của tôi mà tôi không thể loại bỏ.

Mã này với PDO thật đẹp. Tôi vừa chuẩn bị và thực thi hơn 500 truy vấn với rollback ... CÁCH THỨC ĂN!

Đối với lời giải thích thêm một chút bên trong vòng lặp foreach ... mã của bạn nên nhìn simmilar để

$stmt = $db->prepare($query); 
$stmt->execute(array('name', 'age')); 
+0

Thực ra bạn chuẩn bị nó bên ngoài vòng lặp foreach, và chỉ một lần cho mọi kiểu truy vấn, vòng lặp chỉ cần chứa các lệnh gọi '$ stmt-> execute (...)'. Hy vọng điều này làm cho nụ cười của bạn lớn hơn :) –

Các vấn đề liên quan