Home » Php » php – How to insert multiple rows in a mysql database at once with prepared statements?

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

Posted by: admin July 12, 2020 Leave a comment

Questions:

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?

How to&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.

Answer:

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;
}

Answer:

The query looks like this:

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