2013-10-31 96 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()”函数两次。缺乏数据管理。是的,正如你所说的,最好不要一次混合很多查询,代码错误很容易丢失:( –

相关问题