2011-12-15 50 views
0

我花了很多時間進行調試,並在互聯網上尋找解決這個不尋常問題的方法。繼承人:PHP MYSQL在FOR循環中插入語句掛起

我正在處理工單提交和跟蹤系統。涉及兩個數據庫:

  1. 提交數據發佈的數據庫,它位於同一臺物理機器上,但位於與提供php的Web服務器分開的虛擬機上。他們在同一個C類子網上。
  2. 我們的追蹤系統的數據庫。位於不同IP上的不同物理服務器上,也是虛擬機。

我們的工單系統允許多個'請求服務',存儲在一個數組中。在我們的sumbissions數據庫中,這是以逗號分隔的字符串形式存儲的,即「40,60,70」,但在我們的跟蹤系統數據庫中,每個「請求的服務」都需要一個單獨的條目,以允許項目的不同方面由不同的員工在不同的時間跟蹤和完成。

問題是:當我在for循環中放置第二個插入語句,一個用於跟蹤數據庫的插入語句時,它完全掛起,並且可能需要5到15分鐘,然後才能通過代碼中的該點,併發送確認電子郵件。數據也沒有被插入。

當我將它從for循環中取出並且只需在提交數據庫中插入一個插入數據並將其插入到跟蹤系統中時,它就可以正常工作。

首先,生病後,工程的代碼,但只有職位一個「服務」來跟蹤系統:

public function insertOrder() 
{ 
    $services = implode(',', $this->model->chk); 
    $curdate = $this->model->getMySQLDate($this->model->curdate); 
    $dueDate = $this->model->getMySQLDate($this->model->dueDate); 

    $sql = "INSERT INTO orders VALUES(DEFAULT, 
      {$this->sanitize($services)}, 
      {$this->sanitize($curdate)}, 
      {$this->sanitize($this->model->submittedBy)}, 
      {$this->sanitize($this->model->shortDesc)}, 
      {$this->sanitize($this->model->projDetails)}, 
      {$this->sanitize($dueDate)}, 
      {$this->sanitize($this->model->dueDateNotes)}, 
      {$this->sanitize($this->model->approveBy)}, 
      {$this->sanitize($this->model->cost)})"; 

    $this->execute($sql); 

    $this->convertServicesToTracks(); 
    $notes = $this->model->getTracksNotes(); 
    $dueDate = $dueDate.' 12:00:00'; 
    $shortDescNoQuotes = str_replace("\"","'",$this->model->shortDesc); 

    $sqlTracks = "INSERT INTO todos VALUES(DEFAULT, 
      {$this->sanitizeTracks($this->model->chk[0])}, 
      NULL, 
      {$this->sanitizeTracks($shortDescNoQuotes)}, 
      {$this->sanitizeTracks($notes)}, 
      now(), 
      {$this->sanitizeTracks($dueDate)}, 
      NULL, 
      12, 
      NULL, 
      'active', 
      NULL, 
      now());"; 

    //echo $sqlTracks; 

    $this->executeTracks($sqlTacks); 
} private function executeTracks($sql) 
{ 
    $db = $this->getTracksDB(); 


    $this->check4Error($db, $sql); 

    return $result; 
} 

private function getTracksDB() 
{ 
    if (!$this->tracksdb) $this->tracksdb = new mysqli(AbstractSQL::TRACKS_HOST, AbstractSQL::USER, AbstractSQL::PASS, AbstractSQL::TRACKS_SCHEMA); 
    return $this->tracksdb; 
} 

private function convertServicesToTracks() 
{ 
    //converts submission data to tracking system data 
} 



private function sanitizeTracks($arg) 
{ 
    if (!isset($arg)) return "NULL"; 
    if (is_numeric($arg) && !is_double($arg)) return $arg; 
    return "'{$this->getTracksDB()->escape_string($arg)}'"; 
} 

當我加入這個簡單的圍繞第二INSERT語句循環,它掛起,即使該數組只有一個項目!

for($i = 0; $i < count($this->model->chk); ++$i) 
    { 
     $sqlTracks = "INSERT INTO todos VALUES(DEFAULT, 
      {$this->sanitizeTracks($this->model->chk[$i])}, 
      NULL, 
      {$this->sanitizeTracks($shortDescNoQuotes)}, 
      {$this->sanitizeTracks($notes)}, 
      now(), 
      {$this->sanitizeTracks($dueDate)}, 
      NULL, 
      12, 
      NULL, 
      'active', 
      NULL, 
      now());"; 

    //echo $sqlTracks; 

    $this->executeTracks($sqlTacks); 
    } 

任何幫助將不勝感激。我爲長碼片斷道歉!

+0

在這樣的循環中做count()是不好的做法。首先本地化計數,然後在循環中使用該值。 – 2011-12-15 17:32:05

回答

0

它是否遍歷for循環?我看到你有回聲,是否寫出了什麼?它有多少項需要迭代? 5分鐘似乎很長時間,但如果有很多項目可能是爲什麼它需要這麼長時間。你在日誌中看到任何錯誤嗎?

你可能會嘗試的東西是保存在一個變量的計數,所以它不必每次計算。它可能會加快你的循環,但我不確定它會插入數據。

for($i = 0, $count = count($this->model->chk); $i < $count; ++$i) 
    { 
     $sqlTracks = "INSERT INTO todos VALUES(DEFAULT, 
      {$this->sanitizeTracks($this->model->chk[$i])}, 
      NULL, 
      {$this->sanitizeTracks($shortDescNoQuotes)}, 
      {$this->sanitizeTracks($notes)}, 
      now(), 
      {$this->sanitizeTracks($dueDate)}, 
      NULL, 
      12, 
      NULL, 
      'active', 
      NULL, 
      now());"; 

    //echo $sqlTracks; 

    $this->executeTracks($sqlTacks); 
    } 

我發現這個在PHP for循環參考:http://php.net/manual/en/control-structures.for.php

+0

感謝您的幫助,但我有這個更新:它可能與我的PHP代碼無關!我剛剛發現昨天工作的代碼今天導致了相同的掛起。我認爲這可能是我的MYSQL服務器上的防火牆和端口的問題。任何人都可以告訴我在哪裏尋找錯誤日誌?沒有什麼出現在我的mysql日誌中,導致我相信數據甚至沒有那麼遠。但是,也沒有Apache錯誤!有任何想法嗎?? – user1100366 2011-12-15 18:18:42

0

那麼,這可能不是問題,但你不應該普遍使用foreach循環,以避免擊中陣列的部分可能不存在?還有更多關於這here。如果你循環一個空索引,它會破壞你的SQL語句。像這樣:

foreach($this->model->chk as $val)