将多个MySQL语句合并为一个


Combine several MySQL statements into one

我连续快速地进行以下三个调用:

UPDATE job 
   SET jstatus = '9'
 WHERE snum = :u AND jstatus = '7' AND jdate < :d
DELETE FROM job 
 WHERE snum = :u AND jstatus < '7' AND jdate < :d
DELETE FROM jdate 
 WHERE snum = :u AND jdate < :d

每个参数都相同。目前,每种方法都是这样做的:

$STH = $DBH->prepare("
UPDATE job 
   SET jstatus = '9'
 WHERE snum = :u AND jstatus = '7' AND jdate < :d");
$STH->bindParam(':u', $json['u']);
$STH->bindParam(':d', $date);
try{$STH->execute();}catch(PDOException $e){echo $e->getMessage();} 

肯定有办法把它们结合起来吧?我看过$mysqli->multi_query和这个SO问题,但两者似乎都比我想象的更复杂。

我将提供一个答案,假设您使用的是符合ACID的引擎(或者对我们来说,是支持事务的引擎)。

您想要做的是避免代码的复杂性——在这种情况下,它运行3个绑定到1中的查询。维护庞大的查询非常困难,您应该不惜一切代价避免这种情况。

您想要的是让查询尽可能快地执行,并尽可能清晰地阅读和理解。

此外,您需要确保查询全部执行,或者如果其中一个失败,则所有查询都会失败——这是一个事务。您不希望删除失败,但更新成功,这将破坏您的数据完整性。

这就是您应该使用事务的原因。这样做的巨大好处是,你可以像普通人一样查询数据库(一次一个查询),确保一切正常或什么都没发生,而且它几乎就像把所有东西都捆绑到一个巨大的、丑陋的、无法维护的查询中一样快。

这是代码:

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$pdo = new PDO($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try 
{   
    $pdo->beginTransaction();

    /**
     * Repeat for as many queries you wish to execute, I used only 1 for the example
     */
    $stmt = $pdo->prepare("
                UPDATE job 
                SET jstatus = '9'
                WHERE snum = :u AND jstatus = '7' AND jdate < :d");             
    $stmt->bindParam(':u', $json['u']);
    $stmt->bindParam(':d', $date);
    $stmt->execute();
    $pdo->commit();    
} 
catch(PDOException $e) {
    $pdo->rollBack();
    echo 'Error: ' . $e->getMessage();
}

您需要开始事务

pdo交易

p.s.

关于来自wikipedia 的数据库事务的moar

您可以尝试MySQL存储过程

http://www.php.net/manual/en/mysqli.quickstart.stored-procedures.php