2011-07-06 14 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

にsimmilarはず? –

+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

私は各トランザクションがクエリを「グループ化」するので、ループ内のトランザクションに各cat nドッグペアを挿入することで、ループを1つのクエリペアで続行または失敗させることができます。 p.s.あなたのforeachにはロールバックが含まれていますか? –

+0

あなたはあなたのトランザクションを構築した方法で1つのcatクエリーと1つのdogクエリーを実行します。取引のポイントがすべてかどうか、なぜ2で2をグループ化するのですか?私の例ではロールバックを忘れてしまったので、私はそれを編集してより明確にすべきです。 –

+0

はい、あなたの例のロールバックが助けになりました、ありがとうございます。 –

-1

はちょうど私が私のプロジェクトにマイケルJ.V.によって提供されたコードを配置したとき、私は削除できませんでした私の顔に笑顔を持っていたことを、ここでコメントしたかったです。

このコードはPDOで非常に美しいです。私はちょうど準備をしてロールバックして500以上のクエリを実行... どうすれば! foreachループ内のビットの詳細説明については

...あなたのコードは、なぜそれを試してみません

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

実際には、foreachループの外でそれを準備し、あらゆるタイプのクエリに対して1回だけ、ループは '$ stmt-> execute(...)'呼び出しを含む必要があります。これはあなたの笑顔をさらに大きくすることを願って:) –

関連する問題