2011-12-02 21 views
7

Tôi đang cố gắng sử dụng câu trả lời của staticsan trong this question cho các báo cáo đã chuẩn bị. Cho phép lấy ví dụ này:Làm thế nào để chèn nhiều hàng trong một cơ sở dữ liệu mysql cùng một lúc với các câu lệnh chuẩn bị?

$stmt = $mysqli->prepare("INSERT INTO something (userid, time, title) VALUES (?, ?, ?)"); 
$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

Trong câu trả lời staticsan's nổ tung mảng được thêm tất cả các giá trị vào báo cáo kết quả mysql để cuối cùng chúng ta có thể chèn nhiều dữ liệu vào cơ sở dữ liệu chỉ với một tuyên bố. Làm thế nào điều này được thực hiện trong ví dụ của tôi?

+0

Ví dụ bạn có một số cố định của các thông số, do đó, nó đã giải quyết. Bạn có thể giải quyết vấn đề của mình thêm một chút không? Bạn đã thử những gì cho đến nay? Về cơ bản nó sẽ hoạt động giống nhau nhưng thêm nhiều thông số hơn, ví dụ: trong vòng lặp 'foreach'. – hakre

+0

Bạn có thể tạo câu lệnh chuẩn bị bằng cách sử dụng mã như được đề cập ở đây, http://stackoverflow.com/questions/1176352/pdo-prepared-inserts-multiple-rows-in-single-query –

Trả lời

5

này là hoàn toàn hợp lệ:

$stmt = $mysqli->prepare("INSERT INTO something (userid, time, title) VALUES (?, ?, ?)"); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

Bạn có thể foreach qua mảng lại giá trị để chèn và ràng buộc và thực hiện mỗi lần. Nó sẽ không hoàn toàn nhanh như chèn số lượng lớn trong ví dụ bạn đã liên kết, nhưng nó sẽ an toàn hơn.

+1

Cảm ơn, nó hoạt động. Nhưng lệnh execute() sẽ được thực hiện cho mỗi phần tử mảng, do đó mỗi hàng sẽ được chèn vào cơ sở dữ liệu riêng biệt và không phải tất cả cùng một lúc. Tôi có đúng không? Tôi đã hy vọng sẽ thấy một giải pháp mà bạn bind_param đầu tiên tất cả các giá trị và ở cuối cùng thực hiện nó một lần. – phpheini

+0

Vâng, đó là chính xác, nhưng lợi thế chính là tăng tốc độ được cung cấp bởi các tuyên bố chuẩn bị - chuẩn bị các tuyên bố một lần và chạy trong nhiều lần là nhanh hơn nhiều so với chuẩn bị nó mỗi lần. –

+0

Điều này vẫn còn chậm hơn so với truy vấn 'INSERT' tĩnh cũ tốt, phải không? Tôi có nghĩa là, thực hiện các truy vấn trong một vòng lặp tạo ra một sự chậm trễ ~ 2ms giữa mỗi truy vấn. Với mảng lớn này sẽ mất mãi mãi, phải không? – NoobishPro

-2

Truy vấn trông như thế này:

INSERT INTO people (name, age) 
    VALUES 
    ('Helen', 24), 
    ('Katrina', 21), 
    ('Samia', 22), 
    ('Hui Ling', 25), 
    ('Yumie', 29) 
+4

vâng, nhưng không phải cho báo cáo đã chuẩn bị. Câu hỏi là, tôi có phải viết '$ mysqli-> chuẩn bị (" INSERT INTO một cái gì đó (userid, thời gian, tiêu đề) GIÁ TRỊ (?,?,?), (?,?,?), (?,? ,?) ");" và sau đó 'bind_param ('iisiisiis', $ userid [0], thời gian(), $ title, $ userid [0], time(), $ title [0], $ userid [1], time(), $ title [1], $ userid [2], time(), $ title [2]); ' – phpheini

2

Bạn có thể xây dựng tuyên bố sẵn sàng sử dụng mã như đã đề cập ở đây,

PDO Prepared Inserts multiple rows in single query

PHP logic sẽ được loại giống như,

/** 
* Insert With Ignore duplicates in Mysql DB. 
* 
* @param string $date Date. 
*/ 
public static function insertWithIgnore($em, $container, $tableName, $fields, $rows) 
{ 
    $query = "INSERT IGNORE INTO $tableName (`" . implode('`,`', $fields) . "`) VALUES "; 
    $placeHolr = array_fill(0, count($fields), "?"); 
    $qPart = array_fill(0, count($rows), "(" . implode(',', $placeHolr) . ")"); 
    $query .= implode(",", $qPart); 

    $pdo = self::getPDOFromEm($em, $container); 
    $stmt = $pdo->prepare($query); 
    $i = 1; 
    foreach ($rows as $row) { 
     $row['created_at'] = date("Y-m-d H:i:s"); 
     foreach ($fields as $f) { 
      if (!isset($row[$f])) { 
       $row[$f] = null; 
      } 
      $stmt->bindValue($i++, $row[$f]); 
     } 
    } 

    $result = $stmt->execute(); 

    if ($result == false) { 
     $str = print_r($stmt->errorInfo(), true); 
     throw new \Exception($str); 
    } 

    $stmt->closeCursor(); 
    $pdo = null; 
} 

/** 
* Replace old rows in Mysql DB. 
* 
* @param string $date Date. 
*/ 
public static function replace($em, $container, $tableName, $fields, $rows, $extraFieldValues = null) 
{ 
    if ($extraFieldValues != null) { 
     $fields = array_unique(array_merge($fields, array_keys($extraFieldValues))); 
    } 

    $query = "REPLACE INTO $tableName (`" . implode('`,`', $fields) . "`) VALUES "; 
    $placeHolr = array_fill(0, count($fields), "?"); 
    $qPart = array_fill(0, count($rows), "(" . implode(',', $placeHolr) . ")"); 
    $query .= implode(",", $qPart); 

    $pdo = self::getPDOFromEm($em, $container); 
    $stmt = $pdo->prepare($query); 
    $i = 1; 
    foreach ($rows as $row) {    
     if ($extraFieldValues != null) { 
      $row = array_merge($row, $extraFieldValues); 
     } 
     foreach ($fields as $f) { 
      $stmt->bindValue($i++, $row[$f]); 
     }       
    } 
    $stmt->execute(); 
    if (!$stmt) { 
     throw new \Exception("PDO::errorInfo():" . print_r($stmt->errorInfo(), true)); 
    } 
    $stmt->closeCursor(); 
    $pdo = null; 
} 
Các vấn đề liên quan