W3docs

multi_query

Aprenda a usar mysqli_multi_query() em PHP para executar várias instruções SQL em uma única chamada, com exemplos práticos e boas práticas.

Neste artigo, vamos nos concentrar na função mysqli_multi_query() em PHP, que executa uma ou mais instruções SQL em uma única chamada. Abordaremos sua sintaxe, parâmetros e valor de retorno, percorreremos um exemplo executável e explicaremos como ler com segurança vários conjuntos de resultados.

O que é mysqli_multi_query()?

mysqli_multi_query() é uma função embutida do PHP que envia uma ou mais instruções SQL, separadas por ponto e vírgula, ao servidor MySQL em uma única requisição. Ela faz parte da extensão MySQLi, a interface aprimorada do PHP para comunicação com o MySQL.

É útil quando você precisa executar um lote de instruções de uma só vez — por exemplo, populando várias tabelas na inicialização, ou executando um procedimento armazenado que retorna vários conjuntos de resultados. Como cada instrução ainda é executada de forma independente no servidor, mysqli_multi_query() não é um substituto para uma transação quando você precisa de comportamento tudo-ou-nada (veja Quando não usar).

Sintaxe

A função funciona nos estilos procedural e orientado a objetos:

// Procedural style
mysqli_multi_query(mysqli $mysqli, string $query): bool

// Object-oriented style
$mysqli->multi_query(string $query): bool

Parâmetros

ParâmetroDescrição
$mysqliUma conexão válida retornada por mysqli_connect().
$queryUma string com uma ou mais instruções SQL separadas por ponto e vírgula (;).

Valor de retorno

Retorna false se a primeira instrução falhar, caso contrário retorna true. Um valor de retorno true indica apenas que a primeira consulta foi aceita — você deve iterar sobre os resultados para detectar erros nas instruções seguintes.

Como usar mysqli_multi_query()

Chame a função em uma conexão MySQLi válida com uma string de instruções separadas por ponto e vírgula, em seguida percorra os conjuntos de resultados. Veja um exemplo completo:

<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");

if (!$mysqli) {
    die("Connection failed: " . mysqli_connect_error());
}

$query = "INSERT INTO table1 VALUES ('value1', 'value2', 'value3');";
$query .= "UPDATE table2 SET column1 = 'newvalue' WHERE id = 1;";

if (mysqli_multi_query($mysqli, $query)) {
    do {
        if ($result = mysqli_store_result($mysqli)) {
            while ($row = mysqli_fetch_row($result)) {
                print_r($row);
            }
            mysqli_free_result($result);
        }
    } while (mysqli_next_result($mysqli));
} else {
    echo "Error: " . mysqli_error($mysqli);
}

mysqli_close($mysqli);
?>

Veja o que cada parte faz:

  1. mysqli_connect() abre uma conexão com o banco de dados MySQL; abortamos cedo se ela falhar.
  2. Construímos uma única string com duas instruções separadas por ponto e vírgula.
  3. mysqli_multi_query() envia ambas as instruções ao servidor em uma única chamada.
  4. O loop do...while lê cada conjunto de resultados em sequência. mysqli_store_result() armazena em buffer o resultado atual, mysqli_fetch_row() lê suas linhas e mysqli_next_result() avança para o próximo.
  5. mysqli_close() libera a conexão.

Tratando múltiplos conjuntos de resultados

Esta é a parte que os desenvolvedores mais frequentemente erram. Após um mysqli_multi_query() bem-sucedido, você deve consumir todos os conjuntos de resultados — inclusive os vazios produzidos por INSERT ou UPDATE — antes de executar outra consulta na mesma conexão. Ignorar esta etapa gera o erro "Commands out of sync".

O padrão seguro é:

<?php
do {
    // Buffer the current result set, if any.
    if ($result = mysqli_store_result($mysqli)) {
        while ($row = mysqli_fetch_row($result)) {
            print_r($row);
        }
        mysqli_free_result($result);
    }
    // mysqli_more_results() avoids a spurious warning on the last loop.
} while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
?>

mysqli_next_result() retorna false quando não há mais resultados, encerrando o loop. Verificar mysqli_more_results() primeiro evita que um aviso seja emitido após a última instrução.

Quando não usar

mysqli_multi_query() é poderoso, mas fácil de usar incorretamente:

  • Nunca passe entrada do usuário diretamente na string de consulta. Concatenar dados não confiáveis aqui é um vetor clássico de injeção SQL, e esta função não pode usar parâmetros vinculados. Para qualquer coisa que envolva entrada do usuário, execute cada instrução separadamente com prepared statements — veja mysqli_prepare().
  • Não é atômica. Se a segunda instrução falhar, a primeira já terá sido confirmada. Quando várias instruções precisam ter sucesso ou falhar juntas, envolva as consultas individuais em uma transação com mysqli_begin_transaction(), mysqli_commit() e mysqli_rollback().
  • Sempre verifique o valor de retorno e itere os resultados para detectar erros nas instruções após a primeira.

Conclusão

A função mysqli_multi_query() permite executar várias instruções SQL em uma única chamada, o que é conveniente para operações em lote. A chave para usá-la corretamente é consumir todos os conjuntos de resultados com mysqli_next_result() para evitar erros de "Commands out of sync", e recorrer a prepared statements e transações sempre que entrada do usuário ou atomicidade estiverem envolvidas.

Prática

Prática
Qual é o principal objetivo da função 'multi_query' em PHP?
Qual é o principal objetivo da função 'multi_query' em PHP?
Was this page helpful?