2017-05-28 32 views
1

我的數據庫中有三個表(MySQL/InnoDB):pupil,evening_activitypupil_evening_activity。您可以猜到pupilevening_activity之間存在m:m關係。爲m:m關係插入行(pupil-evening_activity)一致

我有一個HTML表單來插入新的學生,並與他們進行晚間活動。提交表格後,我想將學生及其相關活動插入數據庫中。所以我寫了這個代碼:

$db = new PDO('mysql:host=localhost;dbname=school;charset=utf8','root', '****'); 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 


try { 
    $sql = "INSERT INTO pupil 
      (name, surname) 
      VALUES 
      ('test_name', 'test_surname')"; 
$st = $db->prepare($sql); 
$st->execute(); 

    foreach ($eveningActivityIds as $eveningActivityId) { 
    $sql = "INSERT INTO pupil_evening_activity 
       (pupil_id, evening_activity_id) 
       VALUES 
       (?, ?) 
     "; 
    $st = $db->prepare($sql); 
    $st->execute(array($db->lastInsertId(), $eveningActivityId)); 
    } 

} catch (PDOException $e) { 

echo $e->getMessage(); 
return false; 

} 

我寫了代碼期待PDO::lastInsertId()總是返回最後插入學生的ID,但我發現,它真正的返回是在最後插入id整個數據庫。因此,如果另一行只是打電話來$db->lastInsertId()上面的代碼之前插入一個假想teacher$db->lastInsertId()將返回插入的老師,而不是最後的瞳孔idid

那麼我怎樣才能100%安全地提交表格後最後插入idpupil表?

我曾考慮過使用交易和MAX()函數來獲取插入pupil表中的最後id,但我不確定。

回答

0

在foreach循環中有$ db-> lastInsertId()是錯誤的,因爲它可能返回不可預知的值。請考慮以下代碼:

try { 
    $sql = "INSERT INTO pupil 
     (name, surname) 
     VALUES 
     ('test_name', 'test_surname')"; 

    $st = $db->prepare($sql); 
    $st->execute(); 

    // save pupil id into variable here: 
    $pupil_id = $db->lastInsertId(); 

    // also there's no need to prepare the statement on each iteration: 
    $sql = "INSERT INTO pupil_evening_activity 
      (pupil_id, evening_activity_id) 
      VALUES 
      (?, ?)"; 
    $st = $db->prepare($sql); 

    foreach ($eveningActivityIds as $eveningActivityId) { 
     $st->execute(array($pupil_id, $eveningActivityId)); 
    } 
} catch (PDOException $e) { 
    echo $e->getMessage(); 
    return false; 
} 

優化:您可以在一個語句中插入所有acivities。它可以節省你很少的請求

try { 
    $sql = "INSERT INTO pupil 
    (name, surname) 
    VALUES 
    ('test_name', 'test_surname')"; 

    $st = $db->prepare($sql); 
    $st->execute(); 

// save pupil id into variable here: 
    $pupil_id = $db->lastInsertId(); 

    $sql = 'INSERT INTO pupil_evening_activity 
     (pupil_id, evening_activity_id) 
     VALUES '; 

    $values = array(); 

    foreach ($eveningActivityIds as $eveningActivityId) { 
    $sql .= '(?, ?),'; 
    array_push($values, $pupil_id, $eveningActivityId); 
    } 

    $st = $db->prepare(chop($sql, ',')); 
    $st->execute($values); 
} catch (PDOException $e) { 
    echo $e->getMessage(); 
    return false; 
} 
+0

謝謝!很有用!!但是..有關我的主要問題的任何想法?即:使用'PDO :: lastInsertId()'獲取插入'pupil'表中的最後一個'id'是否正確? – ziiweb

+0

我相信這很好,除非你正在構建一個每秒數千次請求的高負荷系統。 –