2010-08-11 8 views
26

Tengo un procedimiento almacenado que no necesita devolver ningún valor. Funciona sin problemas y sin ningún problema. Sin embargo, emite un mensaje de error después de terminar su ejecución:Cómo deshacerse de "Error 1329: sin datos: cero filas recuperadas, seleccionadas o procesadas"

Error: No data - zero rows fetched, selected, or processed

¿Cómo me puedo deshacer de este mensaje de error?

CREATE PROCEDURE `testing_proc`() 
    READS SQL DATA 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE l_name VARCHAR(20); 
    DECLARE my_cur CURSOR FOR 
     SELECT name FROM customer_tbl; 
    OPEN my_cur; 
     my_cur_loop: 
     LOOP FETCH my_cur INTO l_name; 
      IF done = 1 THEN 
       LEAVE my_cur_loop; 
      END IF; 
      INSERT INTO names_tbl VALUES(l_name); 
     END LOOP my_cur_loop; 
    CLOSE my_cur; 
END 
+1

Sin detalles, seré el primero en decir: podría reemplazarse con 'INSERT INTO names_tbl SELECT name FROM CUSTOMER_TBL' =) –

+0

Gracias OMG Ponies. En el código actual "INSERT INTO names_tbl VALUES (l_name);" debe ser reemplazado por 200 líneas de código. Utilicé esta versión simplificada porque recibo el mismo error incluso para esta versión simplificada. Estoy bien para dar salida a varchar como el valor de retorno si ayuda a eliminar el mensaje de error. – Babibo

Respuesta

23

es necesario definir un controlador de continuar así:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

Por lo que se vería así:

DECLARE done INT DEFAULT 0; 
DECLARE l_name VARCHAR(20); 
DECLARE my_cur CURSOR FOR 
    SELECT name FROM customer_tbl; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

OPEN my_cur; 
    my_cur_loop: 
    LOOP FETCH my_cur INTO l_name; 
     IF done = 1 THEN 
      LEAVE my_cur_loop; 
     END IF; 
     INSERT INTO names_tbl VALUES(l_name); 
    END LOOP my_cur_loop; 
CLOSE my_cur; 
34

supongo que simplemente se olvidó de incluir la siguiente línea en su mensaje:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

Su código es Corre ct, pero el comportamiento extraño/error de mysql hace que la advertencia aparezca incluso si se manejó. Puede evitar eso si agrega una declaración "ficticia" al final de su procedimiento que invoca una tabla y es exitosa, esto borrará la advertencia. (Ver http://dev.mysql.com/doc/refman/5.5/en/show-warnings.html) En su caso:

SELECT name INTO l_name FROM customer_tbl LIMIT 1; 

después del final del bucle. En MySQL 5.5.13, la advertencia desaparece, en Linux y Windows. Comenté en MySQL Bug 60840 y espero que lo reparen en el futuro ...

+0

Gracias. esto resolvió un problema oscuro para mí – Cruachan

+0

Incluir una selección ficticia también resolvió este problema para mí. La selección ficticia tenía que estar en la función de nivel externo. No fue suficiente incluirlo en la función con el cursor. – user984003

+0

Tuve el mismo problema y tu solución funcionó para mí. Gracias –

1

No sé si esto solucionó el problema del cursor, pero encontré esta advertencia con una función almacenada y encontré que si se utiliza:

RETURN (SELECT x From myTable...); 

en lugar de

SELECT x into myVar...return myVar 

tengo este útil de este documento: http://bugs.mysql.com/bug.php?id=42834

+0

Muchas gracias, me ayudó –

1

Normalmente esto ocurre cuando sobrepasa un rango de cursor, así que revise las condiciones de bucle donde FETCH es

+1

Esto debería ser un comentario, no una respuesta. Verifique esta [pregunta de metaSO] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) y [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) sobre cómo dar una respuesta correcta. – Yaroslav

3

Intenté las soluciones aquí y ninguna, incluido el controlador de continuar, funcionó para mí. Aún recibo los mensajes en el registro de errores de MySQL. Descubrí esto también con mi "seleccionar ... en ...", que tiene sentido, pero realmente pensé que el manejador de continuar trabajaría para los cursores. De cualquier manera que encontré usando "found_rows()" para saber si alguna de las filas fueron devueltas funcionaba perfectamente. Esto significa que las declaraciones simples de "seleccionar en" tienen que convertirse en cursores, pero no es mucho trabajo y resuelve el problema.

DECLARE v_rowcount  integer unsigned; 
DECLARE cur_entries cursor for 
     select app_name, proc_name, error_code, sum(occurrences) occurrences 
     from that_table...; 
open cur_entries; 
set v_rowcount = found_rows(); 
if v_rowcount > 0 then 
    fetch cur_entries into v_app_name, v_proc_name, v_error_code, v_occurrences; 
    ... 
end if; 
close cur_entries; 

escribí esto en mi blog personal aquí: http://tinky2jed.wordpress.com/technical-stuff/mysql/mysql-no-data-zero-rows-fetched-how-to-code-for-it/

7

me encontré con esto y se retiraron el pelo hasta que me encontré con esto en el official mysql docs

Before MySQL 5.6.3, if a statement that generates a warning or error causes a condition handler to be invoked, the handler may not clear the diagnostic area. This might lead to the appearance that the handler was not invoked. The following discussion demonstrates the issue and provides a workaround.

Haga clic en el enlace y Desplácese hasta la parte inferior para obtener detalles, pero la solución era incluir una selección exitosa. DENTRO del CONTINUO MANEJADOR:

DECLARE CONTINUE HANDLER FOR NOT FOUND 
    BEGIN 
     SELECT 1 INTO @handler_invoked FROM (SELECT 1) AS t; 
    END; 
Cuestiones relacionadas