Chiamata multipla di query

  • Creatore Discussione Creatore Discussione Eugene
  • Data di inizio Data di inizio

Eugene

Utente Attivo
5 Mag 2005
110
0
16
56
Dagobah
www.yodastudio.com
Buonasera.

Questo il mio problema.
Ho una tabella nella quale ogni record contiene dati relativi ad un CD musicale (titolo, autore, ecc.). Tra questi è presente anche il valore booleano "attivo".
Tramite apposito codice vengono contati i record presenti nella tabella e viene scelto un numero casuale (random_call).
Dal momento che il record selezionato potrebbe essere non attivo (ovvero attivo==FALSE) faccio una verifica (random_cd_check).
Nel caso in cui l'esito sia positivo, si procede con l'esecuzione del codice, diversamente viene ripetuta la procedura dall'inizio.

Questo il codice:

PHP:
	function random_call($db){
		$query_random_cd = "SELECT * FROM compactdisc";
		$ris_random_cd = mysql_query($query_random_cd,$db) or die("Errore nella query cd random: ".mysql_error());
		$number=mysql_num_rows($ris_random_cd);
		$rand_number = mt_rand (1,$number);
		$numerello = random_cd_check($rand_number,$db);
		echo "numero fortunello funzione random ".$numerello."\n";
		return $numerello;
		}
		//
	function random_cd_check($rand_number,$db){
		$query_check_random_cd = "SELECT * FROM compactdisc WHERE compactdisc.id='$rand_number' AND compactdisc.attivo=TRUE";
		$ris_check_random_cd = mysql_query($query_check_random_cd,$db) or die("Errore nella query check cd random: ".mysql_error());
		$check_random_cd_total=mysql_num_rows($ris_check_random_cd);
			if ($check_random_cd_total>=1){
				echo "cd attivo!\n";
				echo "numero fortunello funzione check ".$rand_number."\n";
				return $rand_number;
			}else{
				echo "cd non attivo!\n";
				random_call($db);
			}
	}
	//
	$numerello = random_call($db);
	echo "numero fortunello ".$numerello."\n";

Dopo una serie di modifiche e tentativi, ho dedotto che il problema risieda in queste righe:

PHP:
$numerello = random_cd_check($rand_number,$db);
echo "numero fortunello funzione random ".$numerello."\n";
return $numerello;

Questo echo, infatti, non visualizza solo $numerello ricevuto dalla chiamata della funzione random_cd_check (quindi quello corrispondente al record attivo) bensì viene ripetuto per ogni query effettuata, anche quelle che hanno avuto esito negativo.

Se prima del record attivo ne sono stati selezionati casualmente 12 non attivi, il comando echo verrà ripetuto 12 volte anche se solo la prima visualizzazione avrà un valore (ovvero quello ricevuto dalla funzione random_cd_check) poichè gli echo vengono visualizzati in ordine inverso.
Proprio per questo return $numerello non restituisce assolutamente nulla poichè darà l'esito della prima query (il cui esito, nei test che sto effettuando, è quasi sempre negativo poichè tra i record presenti solo uno è attivo, proprio per verificare l'efficienza del codice).


Mi rendo conto di non aver esposto la faccenda nel più chiaro dei modi, mi auguro tuttavia qualcuno riesca a capirci qualcosa e sia in grado di darmi una mano.

Grazie e buona serata.
 
Il comportamento da te riscontrato è normale in quanto il codice che hai scritto è ricorsivo.
Prova così:

PHP:
function random_call($db){
        $query_random_cd = "SELECT * FROM compactdisc";
        $ris_random_cd = mysql_query($query_random_cd,$db) or die("Errore nella query cd random: ".mysql_error());
        $number=mysql_num_rows($ris_random_cd);
      	$numerello = random_cd_check($number, $db);
        echo "numero fortunello funzione random ".$numerello."\n";
        return $numerello;
        }
        //
    function random_cd_check($number, $db){
    		$check_random_cd_total = 0;
    		while ($check_random_cd_total == 0) {
	      	$rand_number = mt_rand (1,$number);
	        $query_check_random_cd = "SELECT * FROM compactdisc WHERE compactdisc.id='$rand_number' AND compactdisc.attivo=TRUE";
	        $ris_check_random_cd = mysql_query($query_check_random_cd,$db) or die("Errore nella query check cd random: ".mysql_error());
	        $check_random_cd_total=mysql_num_rows($ris_check_random_cd);
	      }
	      return $check_random_cd_total;
    }
    //
    $numerello = random_call($db);
    echo "numero fortunello ".$numerello."\n";

Però tieni presente che se tittu i record sono inattivi il ciclo non terminerà mai inoltre, dovresti eliminare
di volta in volta gli id già provati in quanto la funzione mt_rand potrebbe restituirti più volte lo stesso id
e continueresti ad effettuare delle select già eseguite in precedenza.

P.S.
Mi permetto di farti notare che il DB da te utilizzato non è normalizzato in quanto, ad esempio,
un autore ha sicuramente inciso più di un cd e quindi è un'informazione ridondante che ritrovi in ogni record
del DB contenente un CD scritto da quel particolare autore. Sarebbe più corretto creare una tabella autori e, in
generale, una tabella per ogni informazione che potrebbe rivelarsi ridondante.
 
Tutto risolto.

Con il codice:
PHP:
	function random_call($db){
		$query_random_cd = "SELECT * FROM compactdisc WHERE compactdisc.attivo=TRUE ORDER BY rand() LIMIT 1";
		$ris_random_cd = mysql_query($query_random_cd,$db) or die("Errore nella query cd random: ".mysql_error());		
		$number = mysql_fetch_array($ris_random_cd);
		echo "La casualità ha prodotto il seguente risultato: ".$number['id'];
		$selected_number = $number['id'];
		return $selected_number;
		}

seleziono casualmente un record tra quelli attivi, dopodichè ne estraggo l'ID, che è il valore che a me serve. In questo modo funziona anche in caso di ID non consecutivi, meglio di quanto sperassi.

Per quanto riguarda la normalizzazione del database, esistono già delle tabelle per tutti quei dati ridondanti (artisti, titoli brani, paese produttore, ecc.), solo che dal codice riportato non si evince perchè vengono estratti in un secondo momento.

Grazie mille per l'aiuto e buona giornata.

Buona giornata.
 

Discussioni simili