2011-07-05 10 views
6
procedimiento

de llamadas funciona bien en la terminal de MySQL, pero en PHP, causó Commands out of sync; you can't run this command nowCommands out of sync; you can't run this command nowprocedimiento almacenado de MySQL causó `Comandos fuera de sync`

Mi procedimiento es

delimiter $$ 
create procedure getMostSimilar (IN vU_ID INT, IN voffset INT, IN vsize INT) 
BEGIN 
set @offset = voffset; 
set @size = vsize; 
set @uid = vU_ID; 
prepare SimilarStmt from 
"SELECT U_ID, getSimilarity(U_ID, ?) AS similar FROM Answer WHERE U_ID != ? GROUP BY U_ID ORDER BY similar DESC LIMIT ?, ?"; 
execute SimilarStmt using @uid, @uid, @offset, @size; 
deallocate prepare SimilarStmt; 
END 
$$ 

donde getSimilarity es una función.

En PHP:

function getMostSimilar($U_ID, $offset, $size){ 
    $query = sprintf("CALL getMostSimilar(%s, %s, %s)", 
       $U_ID, $offset, $size); 
    $result = mysql_query($query); 
    print mysql_error(); 
    if (!$result){ 
     return $query; 
    } 
    $ans = array(); 
    $len = 0; 
    while($row = mysql_fetch_assoc($result)){ 
     $ans[$len] = $row; 
     $len++; 
    } 
    return $ans; 
} 

¿Qué debo hacer ahora? ¡Gracias!

Respuesta

1

C.5.2.14. Comandos fuera de sincronización Si obtiene Comandos fuera de sincronización; no puede ejecutar este comando ahora en el código de su cliente , está llamando a las funciones del cliente en el orden incorrecto.

Esto puede ocurrir, por ejemplo, si está utilizando mysql_use_result() y tratar para ejecutar una nueva consulta antes de tener llamada mysql_free_result(). También puede ocurrir si intentas ejecutar dos consultas que devuelven datos sin llamando a mysql_use_result() o mysql_store_result() entre ellos.

http://dev.mysql.com/doc/refman/5.0/en/commands-out-of-sync.html

EDITAR

creo que es necesario volver a escribir el procedimiento getMostSimilar almacenado, en lugar de utilizar preparar y ejecutar (que piensa que es engañar a mysql) si utiliza los parámetros en el procedimiento como in this example Creo que su error será reparado.

HTH

+0

Gracias por eso. Lo busqué en Google, pero no parece ser útil. – Ovilia

+0

Creo que el optimizador de mysql está interpretando su función getMostSimilar como recursiva y quiere que libere, use o almacene las devoluciones de datos antes de que haga algo más. – amelvin

+1

Desafortunadamente, MySQL no permitirá las variables en la cláusula LIMIT, por lo que simplemente reescribir el procedimiento para hacer un SELECCIONAR no funcionará – wonk0

12

Parece que hay un error desagradable (o función) que se manifiesta cuando se llama a un procedimiento almacenado que devuelve un conjunto de resultados.. Es decir. un procedimiento almacenado que finaliza con una instrucción select sin una cláusula INTO (ver ejemplo a continuación).

El controlador mysqli (propagablemente) devuelve 2 conjuntos de resultados. El primero es el que regresó del procedimiento almacenado y el segundo un conjunto de resultados vacío y vacío. Es como si se hubiera emitido un comando de consulta múltiple. Una solución para esto (que no se rompe en las consultas habituales (por ejemplo, SELECT)) es consumir este conjunto de resultados ficticio después de procesar el legítimo (el primero).

Ejemplo código php

function do_query($con, $sql) 
{ 
    if (!($result = mysqli_query($con, $sql))) 
    throw new QueryException(mysqli_error($con)); 
    if ($result === true) 
    return true; 
    while ($row = mysqli_fetch_assoc($result)) { 
    // process rows 
    } 
    // Hack for procedures returning second dummy result set 
    while(mysqli_more_results($con)) { 
    mysqli_next_result($con); 
    // echo "* DUMMY RS \n"; 
    } 
} 

Ejemplo procedimiento almacenado:

CREATE PROCEDURE selectStaleHeaders() 
NOT DETERMINISTIC 
SELECT TT.* 
FROM one_pretty_table AS TT 
    LEFT JOIN another AS AN on TT.fk_id = AN.id 
WHERE TT.id IS NULL; 
0

Sé que es tarde y ya hay una respuesta, pero yo estaba recibiendo el mismo mensaje por una razón completamente diferente, así que dejaré mi solución aquí:

fue en realidad un error muy tonto. Fue solo un error tipográfico en el nombre de un parámetro. Mi función tenía un parámetro denominado preferable:

create function call_client (pereferable int, client_id int) returns int 

en el cuerpo de la función, yo estaba usando el parámetro preferable con el nombre equivocado:

if prefered = 1 then 
    ... 
end if; 

vez he cambiado prefered para preferable que comenzó a trabajar de nuevo.

Cuestiones relacionadas