2009-04-29 42 views
27

Tengo dos consultas, de la siguiente manera:¿Cómo ejecutar dos consultas mysql como una en PHP/MYSQL?

SELECT SQL_CALC_FOUND_ROWS Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10; 
SELECT FOUND_ROWS(); 

Quiero ejecutar estas dos consultas en un solo intento.

$result = mysql_query($query); 

Pero dime cómo manejaré cada conjunto de tablas por separado. En realidad, en ASP.NET que utiliza el conjunto de datos que maneja dos consultas como

ds.Tables[0]; 
ds.Tables[1]; .. etc 

¿Cómo puedo hacer lo mismo usando PHP/MySQL?

+0

** Esto es posible ** (ver http://stackoverflow.com/a/28984274/632951) usando el indicador 'CLIENT_MULTI_STATEMENTS'. – Pacerier

Respuesta

32

Actualización: Al parecer posible pasando una bandera para mysql_connect(). Ver Executing multiple SQL queries in one statement with PHP Sin embargo, cualquier lector actual debe evitar el uso de la clase mysql_ y prefiere PDO.

No puede hacer eso usando la aplicación mysql-api habitual en PHP. Simplemente ejecuta dos consultas. El segundo será tan rápido que no importará. Este es un ejemplo típico de micro optimización. No te preocupes por eso

Para el registro, se puede hacer utilizando mysqli y la función mysqli_multi_query.

+3

Estoy básicamente preocupado por el rendimiento, que creo que disminuirá si golpearemos la base de datos dos veces. – Prashant

+1

Haz un punto de referencia si no estás convencido. El tiempo que tardará en ejecutar la consulta SELECT FOUND_ROWS() y recuperar el resultado es insignificante. Ya tiene la conexión, y el conjunto de resultados es extremadamente pequeño (solo un entero). –

+8

BTW, si le preocupa el rendimiento, debería dedicar su tiempo a deshacerse de la declaración LIKE '% prashant%'. Posiblemente sea un problema de rendimiento real. Como regla general: el cuello de botella para la mayoría de las aplicaciones de php no está en php, sino en la base de datos. Si desea dedicarle tiempo a optimizar su aplicación, dedíquela a revisar sus índices y EXPLIQUE sus consultas. –

2

De esta manera:

$result1 = mysql_query($query1); 
$result2 = mysql_query($query2); 

// do something with the 2 result sets... 

if ($result1) 
    mysql_free_result($result1); 

if ($result2) 
    mysql_free_result($result2); 
+0

¿No quería evitar ejecutar mysql_query dos veces? –

+0

Sí, quiero evitar las consultas de mysql dos veces. Y en la respuesta de @Jon Benedicto, él está ejecutando dos consultas. :( – Prashant

+0

Acabo de publicar otra respuesta que muestra cómo ejecutar ambas consultas de una vez con MySQLi. –

0

Se dice en el sitio PHP que multiple queries are NOT permitted (EDIT: Esto sólo es cierto para el mysql extensión mysqli y PDO permiten varias consultas.) . Entonces no puedes hacerlo en PHP, PERO, ¿por qué no puedes simplemente ejecutar esa consulta en otra llamada mysql_query, (como el ejemplo de Jon)? Todavía debería darle el resultado correcto si usa la misma conexión. Además, mysql_num_rows puede ayudar también.

+0

Esto solo es cierto para la extensión mysql. Mysqli y PDO permiten múltiples consultas. –

3

Usando SQL_CALC_FOUND_ROWS no puede.

El recuento de filas disponible a través de FOUND_ROWS() es transitorio y no está previsto que esté disponible después de la instrucción que sigue a la instrucción SELECT SQL_CALC_FOUND_ROWS.

Como alguien señaló en su pregunta anterior, usar SQL_CALC_FOUND_ROWS es con frecuencia más lento que obtener un conteo.

Tal vez sería mejor fuera haciendo esto como subconsulta como:

SELECT 
(select count(*) from my_table WHERE Name LIKE '%prashant%') 
as total_rows, 
Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10; 
+0

SQL_CALC_FOUND_ROWS es más lento, pero en http: //dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows link Encontré "Sin embargo, esto es más rápido que ejecutar la consulta nuevamente sin LIMIT, porque el conjunto de resultados no necesita ser enviado para el cliente. " – Prashant

+1

Pero no en este caso, dado que la consulta no puede usar índices, SQL_CALC_FOUND_ROWS dará como resultado una exploración de tabla única, mientras que su subconsulta dará como resultado dos, y por lo tanto, será mucho más lenta. he olvidado una coma después de total_rows. –

+1

Sí, bueno, no está ejecutando la consulta nuevamente sin el límite. Está ejecutando un conteo (*), que envía una fila. Realmente, Emil H tiene un buen punto: es una micro optimización de du valor bioso Ya sea que ejecute dos consultas, o si es absolutamente necesario que lo haga, hágalo como una subconsulta, tal como lo expliqué. (Emil H, gracias por señalar la coma que falta.) – tpdi

3

Vas a tener que utilizar la extensión mysqli si no desea ejecutar una consulta en dos ocasiones:

if (mysqli_multi_query($link, $query)) 
{ 
    $result1 = mysqli_store_result($link); 
    $result2 = null; 

    if (mysqli_more_results($link)) 
    { 
     mysqli_next_result($link); 
     $result2 = mysqli_store_result($link); 
    } 

    // do something with both result sets. 

    if ($result1) 
     mysqli_free_result($result1); 

    if ($result2) 
     mysqli_free_result($result2); 
} 
2

Usted tiene que usar MySQLi, por debajo de código funciona bien

<?php 
$mysqli = new mysqli("localhost", "my_user", "my_password", "world"); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$query = "SELECT CURRENT_USER();"; 
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5"; 

/* execute multi query */ 
if ($mysqli->multi_query($query)) { 
    do { 
     /* store first result set */ 
     if ($result = $mysqli->store_result()) { 
      while ($row = $result->fetch_row()) { 
       printf("%s\n", $row[0]); 
      } 
      $result->free(); 
     } 
     /* print divider */ 
     if ($mysqli->more_results()) { 
      printf("-----------------\n"); 
     } 
    } while ($mysqli->next_result()); 
} 

/* close connection */ 
$mysqli->close(); 
?> 
7

Como otros han respondido, la API mysqli puede ejecutar consultas múltiples con la función msyqli_multi_query().

Por lo que vale la pena, DOP soporta multi-consulta por defecto, y se puede iterar sobre los múltiples conjuntos de resultados de sus múltiples consultas:

$stmt = $dbh->prepare(" 
    select sql_calc_found_rows * from foo limit 1 ; 
    select found_rows()"); 
$stmt->execute(); 
do { 
    while ($row = $stmt->fetch()) { 
    print_r($row); 
    } 
} while ($stmt->nextRowset()); 

Sin embargo, la consulta múltiple es bastante ampliamente considerado como un mal idea por razones de seguridad. Si no tiene cuidado con la forma de construir las cadenas de consulta, puede obtener el tipo exacto de vulnerabilidad de inyección SQL que se muestra en el classic "Little Bobby Tables" XKCD cartoon. Cuando se usa una API que lo restringe a una sola consulta, eso no puede suceder.

0

Sí, es posible sin utilizar la extensión MySQLi.

Simplemente use CLIENT_MULTI_STATEMENTS en mysql_connect's 5th argument.

Consulte los comentarios a continuación Husni's post para obtener más información.

Cuestiones relacionadas