2011-07-06 34 views
5

在執行它們之前準備多個語句可以嗎?在事務中執行它們之前準備多個語句?

$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 

這會派上用場的地方循環語句2用不同的變量都需要經過相互執行。 這樣的:

$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(); 
} 

我問,因爲我已經在那裏PDO將採取行動車和SQLite的駕駛員引發錯誤的情況,所以我想知道如果上面的例子中甚至應該工作。

p.s.例子是在現場製作的。

+0

爲什麼不試試呢? –

+2

按照您描述的方式使用PDO是完全正確的。唯一的問題是,你在'foreach'語句中使用'beginTransaction()',這違背了事務的目的,但我不知道這是你在輸入這個例子時犯的錯誤還是你實際使用的東西。 –

+0

由pdo sqlite驅動程序引發的錯誤 –

回答

6

因爲評論沒有足夠的空間,所以我會作爲回答發佈。

是的,你可以準備幾個準備好的語句,然後在一個循環中執行它們,沒有什麼不對。

交易部分是錯誤的。如果您想要執行全部查詢或不執行查詢,則需要在循環外啓動事務(與提交相同)。 這就是PHP的try/catch派上用場。

$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

我認爲每個事務都會對這些查詢進行「分組」,因此通過在循環內的事務中插入每個貓狗對將允許循環在一個查詢對上繼續或失敗。附:你的foreach包括rollBack的嗎? –

+0

您將執行1次貓查詢和1次狗查詢您構建交易的方式。交易點是全部或沒有,爲什麼你會將它們分組2?在我的例子中,我忘記了回滾,我編輯了它,所以它應該更清晰。 –

+0

是的,您示例中的回滾確實有幫助,謝謝。 –

-1

只是想在這裏評論,當我把通過邁克爾J.V.提供的代碼到我的項目,我必須在我臉上的笑容,我無法刪除。

此代碼與PDO是如此美麗。我只準備並執行了500多個回滾查詢... HOW ELEGANT

對於foreach循環裏面詳細說明一下......你的代碼看起來應該simmilar到

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

其實你在foreach循環之外準備它,並且對於每種類型的查詢,循環只需要包含'$ stmt-> execute(...)'調用。希望這會讓你的笑容更大:) –

相關問題