2012-06-18 15 views
0

所以我試圖將選定的行從一個表中移動到另一個不同的數據庫中。 。PDO複製不同服務器中的行一般錯誤

它在理論工作(但如果有人想給任何意見,請做,我是很新的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()); 
    } 
} 

回答

2

兩點:

  1. 您在每個迭代上,哪種類型的節省了使用準備好的聲明中的點半準備INSERT - 人你正在使用它逃避。準備好的語句之一是查詢只解析一次,因此如果您需要使用不同的值重複執行相同的查詢,請調用prepare()一次,然後簡單地調用​​並使用不同的數據集可顯着提高性能。

  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()); 

    } 

} 
+0

Hi @DaveRandom。問題是我正在使用2個獨立的數據庫連接。這些表不在同一臺服務器上,因此我首先選擇了行,然後將它們傳遞給另一個表 – mauzilla

+0

@MauritzSwanepoel哦,對不起,我完全錯過了。但關於在循環之外調用'prepare()'的觀點仍然存在。它可能會顯着提升性能。說實話,SQLSTATE代碼並沒有那麼有用 - 我們可以用MySQL中的字符串錯誤(由PDO :: errorInfo()'/'PDOStatement :: errorInfo()'返回的數組的元素'2') – DaveRandom

+0

@ MauritzSwanepoel查看上面的編輯 – DaveRandom

相關問題