Deux fetchAll à la suite

Eléphanteau du PHP | 39 Messages

11 avr. 2010, 19:04

Bonne rencontre,

Je suis confronté a un problème que je ne comprends pas... Je dois avoir louper une information dans la doc ou quelque chose comme ça.

J'utilise du PDO et des procédures stockées. Je construits un formulaire avec deux combo-box qui sont alimentée par le contenu de ma base de données.

Le script de connexion ;
function ouvreConnexion ()
{
	//Information de connexion	
	define('USERNAME','root');
	define('PW','');
	define('DSN','mysql:host=localhost;dbname=garage');
			
			
	try {
		$conn = new PDO(DSN,USERNAME,PW);
	} catch (PDOException $e) {
		print "Erreur !: " . $e->getMessage() . "<br/>";
		die();
	}
	//Retourne la connexion active
	return $conn;
}
Le script avec le formulaire, j'ai juste mis la partie qui pose problème.
				echo '<p>';
					echo '<label for="client" class="oblig">*Client : </lable>';
					echo '<select name="client" id="client" tabindex="1">';							
						echo '<option value=""></option>';				
						//Lancement de procédure stockée pour avoir les villes.	
						try{						
						$stmt = $conn->prepare("CALL AllClient()");
							}
						catch(Exception $e) {
							echo $e->getMessage();
						}
						$stmt->execute();
						//On récupére le résultat et on affiche un message en fonction de celui-ci
						$result = $stmt->fetchAll(PDO::FETCH_BOTH);
						
						foreach($result as $row)
							{
								echo '<option value="'.$row[0].'">'.$row[1].' '.$row[2].'</option>';
							}
						
					echo'</select>';
				echo '</p>';
								echo '<p>';
					echo '<label for="Constructeur" class="oblig">*Constructeur : </lable>';
					echo '<select name="Constructeur" id="Constructeur" tabindex="1">';							
						echo '<option value=""></option>';				
						//Lancement de procédure stockée pour avoir les villes.	
						try{						
						$stmt = $conn->prepare("CALL AllConstructeur()");
							}
						catch(Exception $e) {
							echo $e->getMessage();
						}
						$stmt->execute();
						$result = $stmt->fetchAll(PDO::FETCH_BOTH);
						print_r($result);
						foreach($result as $row)
							{
								echo '<option value="'.$row[0].'">'.$row[1].'</option>';
							}
						
					echo'</select>';
				echo '</p>';
Le premier Combo-box (client)est bien remplis avec les données mais le second (constructeur) est vide. Si j'inverse les deux, la combo-box constructeur est bien remplie mais plus l'autre.

J'ai loupé quoi ?

D'avance, merci.

Cerbère.

Eléphanteau du PHP | 39 Messages

20 avr. 2010, 10:36

Pour info pour résoudre mon souci, j'ai du fermer ma connexion après l'appel de la première procédure stockée. Ensuite, l'ouvrir de nouveau pour la seconde.

ViPHP
ViPHP | 5462 Messages

20 avr. 2010, 10:42

normale faut utiliser PDOStatement->closeCursor
sinon au lieux de faire des try...catch partout utilise la gestion des erreurs
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

Eléphanteau du PHP | 39 Messages

20 avr. 2010, 11:23

normale faut utiliser PDOStatement->closeCursor
sinon au lieux de faire des try...catch partout utilise la gestion des erreurs
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
Ah merci !

Effectivement, c'est plus propre comme ça. ;)

Eléphanteau du PHP | 39 Messages

02 mai 2010, 14:29

Bonne rencontre,

J'ai modifié le code en utilisant le closeCursor(); mais j'ai toujours le même souci.
...
echo '<p>';
	echo '<label for="client" class="oblig">*Client : </label>';
	echo '<select name="client" id="client" tabindex="1">';							
	        echo '<option value=""></option>';				
		//Lancement de procédure stockée pour avoir les villes.					
		$stmt = $conn->prepare("CALL AllClient()");
		$stmt->execute();
		//On récupére le résultat et on affiche un message en fonction de celui-ci
		$result = $stmt->fetchAll(PDO::FETCH_BOTH);
						
		foreach($result as $row)
			{
			     echo '<option value="'.$row[0].'">'.$row[1].' '.$row[2].'</option>';
			}
						
		echo'</select>';
		//L'appel suivant à closeCursor() peut être requis par quelques drivers 
		$stmt->closeCursor();
echo '</p>';
echo '<p>';
	echo '<label for="Constructeur" class="oblig">*Constructeur : </label>';
	echo '<select name="Constructeur" id="Constructeur" tabindex="1">';							
		echo '<option value=""></option>';				
		//Lancement de procédure stockée pour avoir les villes.					
		$stmt2 = $conn->prepare("CALL AllConstructeur()");
		$stmt2->execute();
		$result = $stmt2->fetchAll(PDO::FETCH_BOTH);
		foreach($result as $row)
			{
				echo '<option value="'.$row[0].'">'.$row[1].'</option>';
			}
		//L'appel suivant à closeCursor() peut être requis par quelques drivers 
		$stmt2->closeCursor();
	echo'</select>';
echo '</p>';
...
J'ai vu dans le doc qu'une personne avait le même problème avec les PS et qu'il a du écrire une fonction.
public static function closeCursor($oStm) {
    do $oStm->fetchAll();
    while ($oStm->nextRowSet());
} 
Mais même en l'utilisant, j'ai le même problème. Pour avancer dans mon développement, je ferme la connexion et je l'ouvre de nouveau mais bon... On peut mieux faire...