在事务中执行多个语句之前准备多个语句?

时间:2011-07-06 14:38:45

标签: php pdo

在执行之前准备好多个状态是否可以?

$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。实例是当场制作的。

2 个答案:

答案 0 :(得分:9)

我会发布答案,因为评论不允许有足够的空间。

是的,您可以准备好几个准备好的语句,然后循环执行它们,这没有什么不妥。

交易部分是错误的。如果要执行全部查询或不执行任何查询,则需要在循环之外启动事务(与提交相同)。 这就是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();
}

答案 1 :(得分:-1)

我想在这里发表评论,当我将 Michael J.V。提供的代码放入我的项目中时,我脸上露出笑容,无法移除。

这段代码与PDO是如此美丽。我刚准备并执行了超过500个回滚查询... HOW ELEGANT

有关foreach循环内部的更多解释......您的代码应该看起来与

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