2009-03-23 14 views
16

Uso SQL_CALC_FOUND_ROWS en la instrucción SELECT de Mysql, para obtener el número de líneas que mi SELECT devolvería sin una cláusula LIMIT.SQL_CALC_FOUND_ROWS/FOUND_ROWS() no funciona en PHP

$sql = new mysqli('localhost', 'root', ''); 
$sql->select_db('mysql'); 
$s1 = $sql->query('select SQL_CALC_FOUND_ROWS * from db limit 0, 3'); 
$s2 = $sql->query('select FOUND_ROWS()'); 
if($row = $s2->fetch_row()) printf('%d/%d', $s1->num_rows, $row[0]); 

En mi estación de desarrollo WinXP devuelve 3/0 cada vez durante varias semanas. Cuando uso otro servidor MySQL desde mi estación, devuelve 3/0 también. En otra PC el mismo código funciona bien, y devuelve el número correcto (3/17 por ejemplo, si tengo 17 registros en la tabla mysql.db). Cada PC XP tiene la misma versión PHP/Mysql, y funcionó bien en el pasado en mi PC Utilizando Mysql Query Browser con las mismas consultas SQL obtengo el número correcto.

¿Alguien podría darme una idea de la solución, sin volver a instalar todo?

Lo siento, mi solicitud anterior era muy poco clara.

+1

¿Puede incluir su código PHP? ¿Está pidiendo definitivamente el recuento utilizando el mismo recurso de conexión de base de datos que el utilizado para la consulta? –

+0

Su pregunta carece del error que se produce y del código que está utilizando, con el pulgar hacia abajo. – TravisO

+0

@PaulDixon Gracias Paul! En nuestro código .net, siempre estamos creando nuevas conexiones así que tan pronto como leí su comentario, supe que ese debe ser mi problema. –

Respuesta

14

Gracias.

Cuando ejecuté algo análogo a su ejemplo en la línea de comandos de mysql, funcionaría; pero al ejecutarlo desde php, falló. La segunda consulta tiene que "saber" sobre la primera, así que de alguna forma creo que la persistencia/memoria que vincula las dos consultas estaba siendo arruinada por el php.

(Resulta que Wordpress utiliza este tipo de consulta para hacer su paginación, por lo que nuestro mayor problema fue que la paginación en una instalación de WordPress de repente dejó de funcionar cuando nos movimos a php 5.2.6 ... finalmente la rastreó a FOUND_ROWS()).

Por el simple hecho de publicar para las personas que puedan toparse con esto en el futuro ... para mí fue la configuración de php "mysql.trace_mode" - esta predeterminada en "on" en 5.2.6 en lugar de "off" como anteriormente, y por alguna razón impide que FOUND_ROWS() funcione.

como una "solución", podríamos o bien poner esto en cada página php (en realidad, en un común "incluir"):

ini_set("mysql.trace_mode", "0"); 

o añadir esto al.htaccess:

php_value mysql.trace_mode "0" 

Gracias de nuevo, Jerry

+0

¡¡Bien !! Gracias, es la solución correcta –

8

¿Está utilizando un método de consulta MySQL que permite múltiples consultas.

De la documentación de MySQL.

Para obtener este número de filas, incluyen una opción de SQL_CALC_FOUND_ROWS en la instrucción SELECT, y luego invocar FOUND_ROWS() después

Ejemplo:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name 
    -> WHERE id > 100 LIMIT 10; 
mysql> SELECT FOUND_ROWS(); 

también sólo por diversión, hay una gran discusión sobre la condición de carrera del uso de FOUND_ROWS()here.

+0

La condición de carrera es de esperar, pero sospecho que realmente no es tan importante para una operación como esta. Aún así, es bueno estar al tanto. – Oddman

0

W ell, era un problema con la extensión mysql php incluida con php 5.2.6. Mysqli funciona bien, y otra versión de php también. Lo siento por el ruido y la pregunta poco clara.

Si tiene el mismo problema, mi consejo es volver a instalar PHP o cambiar la versión.

2

Otra manera sería utilizar mysqli_multi_query como se indica en el manual de PHP haciendo pasar ambas consultas que contienen SQL_CALC_FOUND_ROWS y FOUND_ROWS separados por un punto y coma

<?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 SQL_CALC_FOUND_ROWS * FROM db limit 0, 3;"; 
$query .= "SELECT FOUND_ROWS()"; 

/* 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(); 
?> 
+1

Creo que tiene que ser SELECCIONAR FOUND_ROWS() –

+0

Gracias James F, he hecho una corrección. –

0

La solución más rápida es subconsultar su consulta real de esta manera:

SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT whatever FROM whatever WHERE whatever LIMIT whatever) ax; 
select FOUND_ROWS(); 

Ahora obtendrá los resultados correctos. Creo que la razón principal es que SQL_CALC_FOUND_ROWS rastrea principalmente las filas encontradas (es decir, sin LIMITS) no se devuelven las filas.

0

Tuve el mismo problema. La solución fue estúpida, estaba usando $wpdb->query en lugar de $wpdb->get_var. Por lo que desea hacer

$wpdb->get_var('select FOUND_ROWS()'); 

si estás en WordPress