PDO复制不同服务器中的行常规错误

时间:2012-06-18 12:16:13

标签: php mysql pdo

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

它在理论上有效(但是如果有人想提出任何意见请做,我对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());
    }
}

1 个答案:

答案 0 :(得分:2)

两点:

  1. 您正在为每次迭代准备INSERT,这有点消除了使用预准备语句的一半 - 您正在使用它进行转义。准备语句的一个要点是查询只被解析一次,因此如果您需要使用不同的值重复执行相同的查询,请调用prepare()一次,然后只需使用不同的数据调用execute()套装可以显着提升表现。

  2. 这一切都可以在2个查询中完成: 由于使用了两个独立的数据库连接而被删除

  3. 修改

    试试这段代码:

    您可能需要调整错误处理以满足您的需求,尤其是在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());
    
        }
    
    }