据我所知,为了防止注入攻击,PDO :: prepare首先将查询发送到服务器然后参数稍后进行;现在,我觉得这引入了另一个问题:这意味着PDO ::执行后无法回滚,或者我错过了什么?
我在应用程序中有两个表1和2。这两个表不应包含相同的行。当我使用INSERT INTO table1 SELECT FROM Table2时,如果INSERT查询成功,我想DELETE FROM table2。如果其中一个查询失败,我想回滚。所以我有以下代码:
$dbConn->beginTransaction();
$stmt1 = $dbConn->prepare( "INSERT INTO table1 ( field1, field2, field3 )
SELECT field1, field2, field3 FROM table2 WHERE field4 = :field4" );
$stmt1->execute( array( $field4 ) );
$stmt2 = $dbConn->prepare( "DELETE FROM table2 WHERE field4 = :field4" );
$stmt2->execute( array( $field4 ) );
if ( $stmt1->rowCount() > 0 && $stmt2->rowCount() > 0 )
{
$dbConn->commit();
return true;
}
else
{
$dbConn->rollBack();
return false;
}
没有准备好的陈述,这很容易;但有了它,它看起来很难;以前有人做过这样的事吗?
感谢。
答案 0 :(得分:-1)
这并不困难,从我能说的应该可以正常工作。但是我会重构代码以使用异常:
try {
$dbConn->beginTransaction();
$stmt1 = $dbConn->prepare( "INSERT INTO table1 ( field1, field2, field3 )
SELECT field1, field2, field3 FROM table2 WHERE field4 = :field4" );
$stmt1->execute( array( $field4 ) );
$stmt2 = $dbConn->prepare( "DELETE FROM table2 WHERE field4 = :field4" );
$stmt2->execute( array( $field4 ) );
if ( $stmt1->rowCount() > 0 && $stmt2->rowCount() > 0 )
{
$dbConn->commit();
return true;
}
else
{
throw new LogicException('Unequal row counts.');
}
} catch (Exception $e) {
$dbConn->rollBack();
if ($e instanceof LogicException) {
// just return
return false;
} else {
// otherwise rethrow because something we didnt expect to go
// wrong did
throw $e;
}
}
这样我们也会回滚,如果其他东西产生了PDO
这样的异常,或者我们在数据准备过程中可能会做的其他事情。