2013-10-31 134 views
1

我想弄清楚爲什麼Codeigniter在我的數據庫中插入2次相同的行。我使用PDO作爲mySQL的接口。我正在調試它,並且我確定下面的函數沒有被執行兩次。它發生在特定情況下,如果兩個foreache因爲數組爲空而不運行,但是如果其中一個運行錯誤不會發生。CodeIgniter插入兩次相同的條目。在某些情況下

`

public function save_all() //save all information with the launched flag FALSE 
{ 
    include(database_vars_url()); 
    try 
    { 
     $this->add_new_skills(); 

     if(!isset($_SESSION)) 
     { 
      session_start(); 
     } 
     $email = $_SESSION["email"]; 
     $sql = "INSERT INTO $tbl_name_contest (user_id, contest_title, contest_overview, contest_description, 
       contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration, 
       contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit, 
       contest_edit_id, contest_status, contest_delete) 
       VALUES (0, '$this->title', '$this->overview', '$this->description', '$this->category', 
       (SELECT customer_id FROM $tbl_name_customer WHERE user_id = 
       (SELECT user_id FROM $tbl_name_user WHERE user_email='$email')), '$this->prize', 0, '$this->contest_period', 
       '$this->project_period', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT); "; 

     foreach ($this->addon as $value) 
     { 
      $sql = $sql . "INSERT INTO $tbl_rel_contest_addon (add_contest_id, add_addon_id) 
          VALUES ((SELECT contest_id FROM $tbl_name_contest WHERE contest_title = '$this->title' 
          AND contest_overview = '$this->overview' AND contest_prize = '$this->prize'), 
          (SELECT addon_id FROM $tbl_name_addon WHERE addon_name = '$value')); "; 
     } 

     foreach ($this->skills as $value) 
     { 
      $sql = $sql . "INSERT INTO $tbl_rel_contest_skill (required_contest_id, required_skill_id) 
          VALUES ((SELECT contest_id FROM $tbl_name_contest WHERE contest_title = '$this->title' 
          AND contest_overview = '$this->overview' AND contest_prize = '$this->prize'), 
          (SELECT skill_id FROM $tbl_name_skill WHERE skill_name = '$value')); "; 
     } 
     echo $sql; 
     return $this->db->query($sql); 
    } 
    catch(Exception $e) 
    { 
     echo $e->getMessage(); 
    } 
    return 0; 
} 

在這裏,我有一個日誌的MySQL,前兩個選擇所用所謂的 「$這個 - > add_new_skills();」在函數save_all()的開頭。這些SELECT應該也只是一個。這個順序SELECT SELECT,INSERT INSERT,證明函數save_all()沒有被調用兩次,如果它被調用兩次,那麼順序將是SELECT INSERT SELECT INSERT。

138 Connect [email protected] on repsero 
138 Query SELECT skill_name FROM skill WHERE skill_status=2 
138 Query SELECT skill_name FROM skill WHERE skill_status=2 
138 Quit 
139 Connect [email protected] on repsero 
139 Quit 
140 Connect [email protected] on repsero 
140 Query INSERT INTO contest (user_id, contest_title, contest_overview, contest_description, contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration, contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit, contest_edit_id, contest_status, contest_delete) VALUES (0, 'Contest Name', 'Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest ', 'Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description ', 'SEO', (SELECT customer_id FROM customer WHERE user_id = (SELECT user_id FROM user WHERE user_email='[email protected]')), '300', 0, '5','1', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT) 
140 Query INSERT INTO contest (user_id, contest_title, contest_overview, contest_description, contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration, contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit, contest_edit_id, contest_status, contest_delete) VALUES (0, 'Contest Name', 'Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest ', 'Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description ', 'SEO',(SELECT customer_id FROM customer WHERE user_id = (SELECT user_id FROM user WHERE user_email='[email protected]')), '300', 0, '5', '1', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT) 
140 Quit 
+2

CodeIgniter不是問題 - 它必然是**你的**代碼。你確定你不是多次觸發'save_all()'嗎?這是基本的調試。學習調試你自己的代碼。 – naththedeveloper

+0

可以使用日誌消息來檢查代碼是否執行兩次。 – Nishanthan

+0

嗨,謝謝你的回答。我確定save_all()正在執行一次。我用日誌/轉儲檢查了它。 –

回答

2

嗯,我發現,在CI_DB_pdo_driver的_execute()函數的笨體系內不能正常工作,也許這是因爲PHP版本。

function _execute($sql) 
{ 
    $sql = $this->_prep_query($sql); 
    $result_id = $this->conn_id->prepare($sql); 
    $result_id->execute(); 

    if (is_object($result_id)) 
    { 
     if (is_numeric(stripos($sql, 'SELECT'))) 
     { 
      $this->affect_rows = count($result_id->fetchAll()); 
      $result_id->execute(); 
     } 
     else 
     { 
      $this->affect_rows = $result_id->rowCount(); 
     } 
    } 
    else 
    { 
     $this->affect_rows = 0; 
    } 

    return $result_id; 
} 

TO:反正我從改變笨的代碼

function _execute($sql) 
{ 
    $sql = $this->_prep_query($sql); 
    $result_id = $this->conn_id->prepare($sql); 
    $result_id->execute(); 

    if (is_object($result_id)) 
    { 
     if (preg_match('/^\s*"?(SELECT)\s+/i', $sql)) 
     { 
      $this->affect_rows = count($result_id->fetchAll()); 
      $result_id->execute(); 
     } 
     else 
     { 
      $this->affect_rows = $result_id->rowCount(); 
     } 
    } 
    else 
    { 
     $this->affect_rows = 0; 
    } 

    return $result_id; 
} 

,測試如果$ sql中包含「SELECT」裏面沒有工作的一部分,所以當我試圖插入「$ result_id-> execute()」被調用兩次。

+0

+1這個問題讓我難以忘懷,我正在做一個插入選擇。我將這個問題稱爲CodeIgniter錯誤,因爲CI編程它來檢查它是否是select語句的方式是查看查詢中是否存在select。由於我在做一個插入選擇,它從select語句返回了0個受影響的行,而不是由插入返回的1個受影響的行。 –

+0

實際上我不知道爲什麼CodeIgniter如果是SELECT查詢就調用「execute()」函數兩次。缺乏數據管理。是的,正如你所說的,最好不要一次混合很多查詢,代碼錯誤很容易丟失:( –

相關問題