2013-12-11 2 views
0

Я хочу вставить сразу 20 значений через объекты данных PHP. На данный момент я делаю это так, кажется, очень некрасиво:Вставить несколько значений через PHP PDO в базу данных MySQL

$stmt = $this->pdo->prepare("INSERT INTO <tablename> (`uid`, `mid`, `status`) 
           VALUES (:uid, :mid1, :status), (:uid, :mid2, :status), 
             (:uid, :mid3, :status), (:uid, :mid4, :status), 
             (:uid, :mid5, :status), ... and so on ..."); 
    $stmt->bindParam(':uid', $this->uid); 

    $random_mid = array_rand(range(1,20), 5); 

    $ref = new Mooney($random_mid[0]); 
    $myMid1 = $ref->getMid(); 
    $stmt->bindParam(':mid1', $myMid1); 

    $ref = new Mooney($random_mid[1]); 
    $myMid2 = $ref->getMid(); 
    $stmt->bindParam(':mid2', $myMid2); 

    $ref = new Mooney($random_mid[2]); 
    $myMid3 = $ref->getMid(); 
    $stmt->bindParam(':mid3', $myMid3); 

    ... and so on ... 

    $status = 'open'; // default starting value of status 
    $stmt->bindParam(':status', $status); 
    $stmt->execute(); 

Есть ли лучшее решение, используя для цикла или так? Надеюсь, вы сможете предложить лучшее решение/более красивое решение. Спасибо за ваше время и помощь!

EDIT 1: Теперь благодаря @Jurik код работает и выглядит следующим образом:

private function insertValuesAtOnce() { 
    $stmt = $this->pdo->prepare('INSERT INTO `<tablename>` (`uid`, `mid`, `status`) VALUES (:UID, :MID, :STATUS)'); 
    $random_mid = $this->UniqueRandomNumbersWithinRange(1, 20, 7); 
    require_once('<some path>'); 
    $status = 'open'; 
    foreach($random_mid AS $val){ 
     $ref = new Mooney($val); 
     $myMid = $ref->getMid(); 

     $stmt->execute(array(
      ':UID' => $this->uid, 
      ':MID' => $myMid, 
      ':STATUS' => $status 
     )); 
    } 
} 

Но мне кажется, что это не «вставить много строк сразу», но более «вставить одну строку несколько раз»

EDIT 2: Поскольку невозможно сразу вставить все значения, я буду использовать решение, чтобы вставлять их по строкам, но вставляя их в сделка! Это улучшило время работы от 0,3915548324585 сек/сериализовать до 0,074591159820557 сек/сериализовать.

private function insertValuesAtOnce() { 
    $stmt = $this->pdo->prepare('INSERT INTO `<tablename>` (`uid`, `mid`, `status`) VALUES (:UID, :MID, :STATUS)'); 
    $random_mid = $this->UniqueRandomNumbersWithinRange(1, 20, 7); 
    require_once('<some path>'); 
    $status = 'open'; 

    // Beginn Transaction (ACID)  
    $this->pdo->beginTransaction(); 

    foreach($random_mid AS $val){ 
     $ref = new Mooney($val); 
     $myMid = $ref->getMid(); 

     $stmt->execute(array(
      ':UID' => $this->uid, 
      ':MID' => $myMid, 
      ':STATUS' => $status 
     )); 
    } 
    // End Transaction (ACID) 
    $this->pdo->commit(); 
} 
+0

вопрос: почему вы хотите вставить их сразу? Поскольку ваш 'getMid()' получает данные из базы данных, которая нуждается в базе данных ** перед **, что-нибудь еще вставляет в db? – Jurik

+0

Проблемы с производительностью? – m33x

+0

Исправлена ​​ошибка с использованием транзакций! – m33x

ответ

2
<?php 
    $db = new PDO('mysql:host=localhost;dbname=<SOMEDB>', '<USERNAME>', 'PASSWORD'); 
    $query = $db->prepare(
    'INSERT INTO `user_mooney` (`uid`, `mid`, `status`) 
    VALUES (:UID, :MID, :STATUS)' 
); 

    foreach($random_mid AS $val){ 
    $ref = new Mooney($val); 
    $myMid = $ref->getMid(); 

    $query->execute(array(
     ':UID' => $uid, 
     ':MID' => $myMid, 
     ':STATUS' => $status 
    )); 
    } 

    $query->commit(); 

Если совершать броски ошибки вы можете вызвать $query->rollback(); Так у Вас есть база данных состоят.

Edit: взял правильный ответ от вопроса редактировать 2

<?php 
    private function insertValuesAtOnce() { 
     $stmt = $this->pdo->prepare('INSERT INTO `<tablename>` (`uid`, `mid`, `status`) VALUES (:UID, :MID, :STATUS)'); 
     $random_mid = $this->UniqueRandomNumbersWithinRange(1, 20, 7); 
     require_once('<some path>'); 
     $status = 'open'; 

     // Beginn Transaction (ACID)  
     $this->pdo->beginTransaction(); 

     foreach($random_mid AS $val){ 
      $ref = new Mooney($val); 
      $myMid = $ref->getMid(); 

      $stmt->execute(array(
       ':UID' => $this->uid, 
       ':MID' => $myMid, 
       ':STATUS' => $status 
      )); 
     } 
     // End Transaction (ACID) 
     $this->pdo->commit(); 
    } 
+0

Это сделало трюк, большое спасибо. Насколько я понимаю код, он вставляет значения один за другим и поэтому ** не сразу **, как я просил? Я прав? В любом случае, спасибо! – m33x

+0

Ну, он готовит вставку один за другим, и если вы хотите, вы можете заблокировать базу данных, прежде чем запускать эту вставку. Или вы сначала создаете массив из всех массивов в '$ query-> execute', а затем помещаете этот массив в выполнение. Итак, вы все подготовили, прежде чем сделать первую вставку. – Jurik

+0

Обновленный ответ - но я не уверен, что это возможно, попробуйте, и это будет соответствовать вашему вопросу. – Jurik

Смежные вопросы