Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert multiple rows in a mysql database at once with prepared statements?

I am trying to use staticsan´s answer in this question for prepared statements. Lets take this example:

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

In staticsan´s answer imploding the array is adding all the values into the mysql statement so that in the end we can insert multiple data into the database with just one statement. How would this be done in my example?

like image 939
Chris Avatar asked Dec 02 '11 20:12

Chris


2 Answers

This is completely valid:

$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();

You can foreach over your array of values to insert and bind and execute each time. It wont be quite as fast as the bulk insert in the example you linked, but it will be more secure.

like image 108
Jonathan Rich Avatar answered Sep 26 '22 23:09

Jonathan Rich


You can build prepared statement using code as mentioned here,

PDO Prepared Inserts multiple rows in single query

PHP logic will be sort of like,

/**
 * Insert With Ignore duplicates in Mysql DB.
 */
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.
 */
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;
}
like image 22
Hemant Thorat Avatar answered Sep 23 '22 23:09

Hemant Thorat