0

所以我试图将选定的行从一个表“移动”到不同数据库中的另一个表。

它在理论上可行(但如果有人想发表任何意见,请这样做,我对 PDO 很陌生。但是我不断收到“SQLSTATE [HY000]:一般错误”错误。

有什么建议吗?

  private function broken() {
    try {
        $sql = "SELECT * FROM `calls` WHERE `calls`.`status`=0 AND `calls`.`stage` < 4 AND `calls`.`answer` < (NOW() + INTERVAL 10 MINUTE)";
        $query = $this->staging->query($sql);
        while($row = $query->fetch(PDO::FETCH_ASSOC)) {

            // Insert in production database:
            $sql = "INSERT INTO `ivr_incomplete` (`id`,`sip_id`,`extension`,`caller_id`,`stage`,`status`,`survey_id`,`start`,`answer`,`hangup`,`end`) VALUES (:id, :sip_id, :extension, :caller_id, :stage, :status, :survey_id, :start, :answer, :hangup, :end)";
            $query = $this->production->prepare($sql);
            $query->execute($row);

            // Delete from staging:
            $sql = "DELETE FROM `calls` WHERE `id`='".$row['id']."'";
            $this->staging->query($sql);

        }
    }
    catch(PDOException $e) {
        $this->informer("FATAL", "Unable to process broken IVR surveys. Error: ".$e->getMessage());
    }
}
4

1 回答 1

2

两点:

  1. 您正在为INSERT每次迭代做准备,这在某种程度上消除了使用准备好的语句的一半意义——您使用它的目的就是转义。准备好的语句的要点之一是查询只解析一次,因此如果您需要使用不同的值重复执行相同的查询,调用prepare()一次然后简单地execute()使用不同的数据集调用可以显着提高性能。

  2. 整个事情可以在 2 个查询中完成: 由于使用了两个单独的数据库连接而被删除

编辑

试试这个代码:

您可能需要调整错误处理以满足您的需求,特别是如果 出现错误时如何处理它INSERT,因为我怀疑您是否想要中断整个操作并将已成功处理的行留在源表。

private function broken() {

    try {

        // Fetch records to move
        $sql = "
          SELECT *
          FROM `calls`
          WHERE `status` = 0
            AND `stage` < 4
            AND `answer` < (NOW() + INTERVAL 10 MINUTE)
        ";
        $query = $this->staging->query($sql);
        if (!$query) {
            $errorInfo = $this->staging->errorInfo();
            throw new Exception("MySQL error at SELECT: $errorInfo[1] ($errorInfo[0]): $errorInfo[2]");
        }

        // Prepare the INSERT statement
        $sql = "
          INSERT INTO `ivr_incomplete`
            (`id`,`sip_id`,`extension`,`caller_id`,`stage`,`status`,`survey_id`,`start`,`answer`,`hangup`,`end`)
          VALUES
            (:id, :sip_id, :extension, :caller_id, :stage, :status, :survey_id, :start, :answer, :hangup, :end)
        ";
        if (!$stmt = $this->production->prepare($sql)) {
            $errorInfo = $this->production->errorInfo();
            throw new Exception("MySQL error at prepare INSERT: $errorInfo[1] ($errorInfo[0]): $errorInfo[2]");
        }

        // A list of the row IDs we are working with
        $rowIds = array();

        // Loop the results and insert them
        for ($i = 1; $row = $query->fetch(PDO::FETCH_ASSOC); $i++) {

            if (!$stmt->execute($row)) {
                $errorInfo = $stmt->errorInfo();
                throw new Exception("MySQL error at INSERT row $i (id: {$row['id']}): $errorInfo[1] ($errorInfo[0]): $errorInfo[2]");
            }

            $rowIds[] = (int) $row['id'];

        }

        // Delete from staging:
        if ($rowIds) {

            $sql = "
              DELETE FROM `calls`
              WHERE `id` IN (".implode(', ', $rowIds).")
            ";
            if (!$this->staging->query($sql)) {
                $errorInfo = $this->staging->errorInfo();
                throw new Exception("MySQL error at DELETE: $errorInfo[1] ($errorInfo[0]): $errorInfo[2]");
            }

        }

    } catch(PDOException $e) {

        $this->informer("FATAL", "Unable to process broken IVR surveys (PDO). Error: ".$e->getMessage());

    } catch (Exception $e) {

        $this->informer("FATAL", "Unable to process broken IVR surveys (MySQL). Error: ".$e->getMessage());

    }

}
于 2012-06-18T12:25:40.663 回答