entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

multi_query cachar número de consulta que causó error

Tengo una serie de consultas, las que quiero ejecutar son dos, pero para efectos de prueba he "rellenado" con los selects para crear un escenario y resulta que el insert es el que "debería" de fallar pero la posición de $i no corresponde en éste caso al 4.
Leí unos artículos y no se recomienda el uso de multi_query si se necesita un dato anterior; supongo por el motivo de ese issue que no sé cómo cachar el número del query que no se ejecutó. Hago ésta pregunta con el fin de resolver mi duda, cambiaré a consultas por separado pero no me quiero quedar con la duda.

    $statements = array("UPDATE productos SET precioID = $productID WHERE id = $productID",
                        "SELECT * FROM productos WHERE id = 1",
                        "SELECT * FROM productos WHERE id = 2",
                        "SELECT * FROM productos WHERE id = 3",
                        "INSERT INTO precios (id, publico, constructor, socio) VALUES ($productID, $publico, $constructor, $socio)","SELECT * FROM producto WHERE id = 4");

    if ($getConnection->multi_query(implode(';', $statements))) {
      $i = 0;
      do {
        if ($result = $getConnection->store_result()) {
          // store first result set
          if ($result = $getConnection->store_result()) {
              while ($row = $result->fetch_row()) {
                  // do something with the row
              }
              $result->free();
          } else {
            // report error
          }
        }
        $i++;
      } while ($getConnection->next_result());

1 Respuesta

2votos

Leonardo-Tadei Puntos227320

Hola @migbriones,

en tu código hay algo "raro"... Estás cargando las consultas a ejecutar en un vector, pero lo que debe recibir como parámetro $getConnection->multi_query() es un string.

Luego, al llamar a la función, hacés un implode() separando por ; pero en tu string con las consultas tenés una coma como separador. Además de que el implode() devolverá un solo resultado aplicado a ese string, no es un string lo que recibe...

La variable $statements debería ser un string con todas las querys separadas por ; y pasarle ese string a multi_query(). No verás errores, porque cuando usás un vector como un string, PHP devuelve la cadena "array", que es un string válido por inútil en este caso.

Una vez aclarado esto, la forma de obtener el error de un multi_query() es ver si mysqli_store_result() devuelve falso.

La llamada a mysqli_store_result() devolverá FALSE si la primer sentencia está mal, y luego de llamar a mysqli_next_result() hará lo mismo con la siguiente, y así hasta el final.

Te dejo una porción de código que revisa el error de cada sentencia, basada en el ejemplo del manual de PHP:

<?php
$mysqli = new mysqli("localhost", "mi_usuario", "mi_contraseña", "world");

/* comprobar conexión */
if (mysqli_connect_errno()) {
    printf("Conexión fallida: %s\n", mysqli_connect_error());
    exit();
}

// Concatena las querys, separadas por ;
$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* ejecutar multi consulta */
if ($mysqli->multi_query($query)) {
    do {
        /* almacenar primer juego de resultados */
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->free();
        } else {
            // Esta sentencia da error, hacer algo
        }
        /* mostrar divisor */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
    } while ($mysqli->next_result());
}

/* cerrar conexión */
$mysqli->close();
?>

Dicho esto, y dado que cada sentencia se ejecuta por separado, no debería haber demasiada diferencia con ejecutarlas de a una. La ventaja de multi_query() es poder armar varias sentencias durante el día para ejecutar un proceso batch más tarde por ejemplo.

Saludos cordiales

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta