W3docs

Inserindo Múltiplos Registros em um Banco de Dados MySQL com PHP

Aprenda a inserir múltiplos registros em um banco de dados MySQL com PHP de forma eficiente usando INSERT em lote, prepared statements e multi_query.

Inserir registros um de cada vez significa uma viagem de ida e volta ao servidor de banco de dados por linha — lento e ineficiente quando você tem centenas ou milhares de linhas para carregar. Agrupá-los em uma única instrução INSERT permite que o MySQL analise, planeje e confirme todo o lote de uma vez, o que é drasticamente mais rápido.

Este capítulo apresenta três maneiras de inserir múltiplas linhas com a extensão mysqli do PHP:

  1. Uma única instrução INSERT ... VALUES (...), (...) — o modo mais simples e rápido de inserção em lote.
  2. Um prepared statement iterado sobre seus dados — seguro contra injeção de SQL, ideal quando os valores vêm dos usuários.
  3. mysqli_multi_query() — executar várias instruções distintas agrupadas em uma única string.

Se você ainda não se conectou a um banco de dados, comece com Conectando ao MySQL com PHP. Para inserir uma única linha, consulte Inserir Dados no MySQL.

Estabelecendo uma Conexão

Todos os exemplos abaixo assumem uma conexão mysqli aberta em $conn. Criamos uma com mysqli_connect() e paramos logo se ela falhar:

<?php
$servername = "localhost";
$username   = "username";
$password   = "password";
$dbname     = "database_name";

// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);

// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
?>

Método 1: Um INSERT com Múltiplos Conjuntos de Valores

A maneira mais rápida de adicionar muitas linhas é uma única instrução INSERT INTO que lista vários conjuntos de valores separados por vírgula. O MySQL os insere todos em uma única operação:

<?php
$sql = "INSERT INTO users (firstname, lastname, email)
        VALUES ('John', 'Doe', '[email protected]'),
               ('Mary', 'Moe', '[email protected]'),
               ('Julie', 'Dooley', '[email protected]')";

if (mysqli_query($conn, $sql)) {
    // mysqli_affected_rows() reports how many rows were inserted
    $count = mysqli_affected_rows($conn);
    echo "$count records inserted successfully.";
} else {
    echo "Error inserting records: " . mysqli_error($conn);
}
?>

mysqli_query() aceita dois argumentos — a conexão e a string SQL — e retorna true em caso de sucesso ou false em caso de falha. Após uma inserção bem-sucedida, mysqli_affected_rows() informa quantas linhas foram realmente gravadas (aqui, 3).

Use este método quando os dados são confiáveis (hard-coded ou já sanitizados). Como os valores são concatenados diretamente na string SQL, não é seguro para entradas brutas do usuário — é exatamente isso que o Método 2 resolve.

Método 2: Prepared Statement em um Loop

Quando os valores vêm de um formulário, uma API ou qualquer fonte não confiável, construa a consulta com um prepared statement para que os dados sejam enviados separadamente do SQL. Isso bloqueia a injeção de SQL e permite reutilizar a mesma instrução compilada para cada linha:

<?php
$users = [
    ['John',  'Doe',    '[email protected]'],
    ['Mary',  'Moe',    '[email protected]'],
    ['Julie', 'Dooley', '[email protected]'],
];

// Prepare once with placeholders
$stmt = mysqli_prepare($conn, "INSERT INTO users (firstname, lastname, email) VALUES (?, ?, ?)");

// Bind PHP variables to the placeholders ("sss" = three strings)
mysqli_stmt_bind_param($stmt, "sss", $firstname, $lastname, $email);

foreach ($users as [$firstname, $lastname, $email]) {
    mysqli_stmt_execute($stmt);   // runs with the current variable values
}

echo count($users) . " records inserted safely.";
mysqli_stmt_close($stmt);
?>

A string de tipo "sss" informa ao MySQL que os três parâmetros vinculados são strings. Use i para inteiros, d para doubles/floats e b para blobs. Para um guia completo, consulte PHP MySQL Prepared Statements.

Para máxima velocidade com milhares de linhas, envolva o loop em uma transação para que o MySQL confirme uma vez em vez de após cada execução:

<?php
mysqli_begin_transaction($conn);
foreach ($users as [$firstname, $lastname, $email]) {
    mysqli_stmt_execute($stmt);
}
mysqli_commit($conn);
?>

Método 3: mysqli_multi_query()

Os métodos acima inserem em uma tabela com uma instrução. Quando você precisa executar várias instruções diferentes de uma vez — por exemplo, inserindo em duas tabelas — use mysqli_multi_query(), que executa múltiplas instruções SQL separadas por ponto e vírgula a partir de uma única string:

<?php
$sql  = "INSERT INTO users (firstname, lastname) VALUES ('John', 'Doe');";
$sql .= "INSERT INTO users (firstname, lastname) VALUES ('Mary', 'Moe');";
$sql .= "INSERT INTO logs (action) VALUES ('bulk import')";

if (mysqli_multi_query($conn, $sql)) {
    echo "Multiple statements executed successfully.";
} else {
    echo "Error: " . mysqli_error($conn);
}
?>

Atenção: mysqli_multi_query() aceita instruções agrupadas arbitrariamente, portanto é arriscado com qualquer entrada fornecida pelo usuário — nunca construa sua string a partir de dados não confiáveis. Para inserções em lote simples, prefira o Método 1 ou o Método 2.

Obtendo os IDs Inseridos

Após a inserção, mysqli_insert_id() retorna o id AUTO_INCREMENT gerado pela última linha inserida. Com uma inserção multi-linha, ele fornece o id da primeira linha do lote; as linhas subsequentes seguem sequencialmente. Consulte Obter o ID do Último Registro Inserido para mais detalhes.

Fechando a Conexão

O mysqli fecha a conexão automaticamente quando o script termina, mas é uma boa prática liberá-la explicitamente quando você terminar:

<?php
mysqli_close($conn);
?>

Qual Método Devo Usar?

SituaçãoMelhor escolha
Dados confiáveis e fixos; velocidade máximaMétodo 1 — um INSERT multi-valor
Valores de usuários / entrada externaMétodo 2 — loop com prepared statement
Várias instruções diferentes de uma vezMétodo 3 — mysqli_multi_query()

Conclusão

Agrupar inserções transforma muitas viagens lentas em uma operação rápida. Use um único INSERT multi-valor quando os dados são confiáveis, um prepared statement em loop (envolto em uma transação para lotes grandes) quando vierem de usuários, e mysqli_multi_query() apenas quando você realmente precisar executar instruções distintas juntas. Independentemente do método, valide sua entrada e verifique mysqli_error() para que falhas nunca passem silenciosamente.

Prática

Prática
O que a função mysqli_multi_query() faz em PHP?
O que a função mysqli_multi_query() faz em PHP?
Was this page helpful?