6

Ho scritto una FUNZIONE memorizzata che chiama se stessa, in modo ricorsivo.MySQL non supporta le funzioni ricorsive? perché? da quando?

Tuttavia quando l'eseguo in una query ottengo questo errore spudorato:

Error: 1424 SQLSTATE: HY000 (ER_SP_NO_RECURSION)

Message: Recursive stored functions and triggers are not allowed.

"Non consentito"?
Giusto. Perché non disabilitiamo anche i loop WHILE, mentre ci siamo?

Posso abilitare le funzioni ricorsive in alcun modo?
Ho trovato un bug report, ma ci sono soluzioni alternative?
Sto eseguendo MySQL 5.1.41 su Windows XP (XAMPP Server).

+2

Un database è per il recupero dei dati, non per la programmazione. C'è qualche ragione per cui stai cercando di eseguire una logica complessa, difficile da prevedere o ottimizzare in una stored procedure anziché nell'applicazione? – Borealid

+0

http://stackoverflow.com/questions/3438111/mysql-stored-procedure-that-calles-itself-recursively – Novemberland

+1

Un errore svergognato! C'è un modo per abilitare le funzioni ricorsive; devi modificare il codice MySQL per farli funzionare. –

risposta

3

Nessun problema, Jenco. Non è così efficiente come funzioni di PostgreSQL, ma è possibile nelle procedure di MySQL anche:

DELIMITER $$ 
DROP PROCEDURE IF EXISTS test.factorial_proc$$ 
CREATE PROCEDURE test.factorial_proc 
(
    IN n BIGINT, 
    OUT res BIGINT 
) 
BEGIN 
    SET max_sp_recursion_depth=10; 
    IF n >= 2 THEN 
    CALL test.factorial_proc (n-1, res); 
    SELECT n * res INTO res; 
    ELSE 
    SELECT n INTO res; 
    END IF; 
END$$ 
DELIMITER ; 

[test]> CALL test.factorial_proc (5, @res); 
[test]> CALL test.factorial_proc (5, @res1); 
[test]> select @res * @res1; 
+--------------+ 
| @res * @res1 | 
+--------------+ 
|  14400 | 
+--------------+ 

Sergei Zaytsev.

4

MySQL 5.1 supporta le stored procedure ricorsive, ma non le funzioni ricorsive. Citando il docs:

Stored functions cannot be recursive.

Recursion in stored procedures is permitted but disabled by default. To enable recursion, set the max_sp_recursion_depth server system variable to a value greater than zero. Stored procedure recursion increases the demand on thread stack space. If you increase the value of max_sp_recursion_depth , it may be necessary to increase thread stack size by increasing the value of thread_stack at server startup.

+0

Mi piacerebbe ancora una soluzione utilizzando FUNCTIONS perché ho un metodo ricorsivo che si chiama in attesa di valori di ritorno. Se avessi usato una PROCEDURA, non potrei farcela ... dovrei? –

+1

@Jenko: Tutto ciò che può essere fatto usando la ricorsione può essere riscritto usando l'iterazione: http://stackoverflow.com/questions/931762/can-every-recursion-be-converted-into-iteration –

3

Probabilmente ricorsione in routine memorizzate è scoraggiato perché MySQL ha bisogno di limitare le dimensioni dello stack suoi fili.

MySQL utilizza in genere un thread per connessione. 100 o 1000 di connessioni sono comuni.

Su piattaforme a 32 bit, quando si eseguono 1.000 thread è presente una pressione dello spazio di indirizzo significativa, pertanto è necessario impostare gli stack in modo molto piccolo per evitare l'esaurimento dello spazio dell'indirizzo.

Lo straripamento dello stack è, ovviamente, molto grave - non può essere recuperato da sicuro. Quindi penso che MySQL lo faccia per prevenire gli overflow dello stack, specialmente su piattaforme a 32 bit.

Detto questo, chiunque utilizza un sistema operativo a 32 bit per un server MySQL di produzione al giorno d'oggi è pazzo.

+0

"L'overflow dello stack è, ovviamente , molto male - non può essere recuperato da sicuro "questo è assolutamente sbagliato. TUTTI i linguaggi di programmazione di livello superiore ragionevoli riescono a recuperare in modo sicuro dagli overflow dello stack, come Java, Perl, Python, ... – intgr