par
Cyrano » 09 janv. 2007, 18:10
Salut tout le monde,
je me heurte à un irritant. J'ai trouvé dans la doc de MySQL un exemple tout à fait pratique de procédure stockée pour lister les options d'une colonne de type ENUM. En ligne de commande, ça fonctionne parfaitement bien.
Pour illustrer et surtout pour ceux que ça intéresse, voici dans un premier temps le code de cette procédure :
Code : Tout sélectionner
DELIMITER $$
CREATE PROCEDURE `GetEnumChoiceList`(IN dbName VARCHAR(80), IN tableName VARCHAR(80), IN columnName VARCHAR(80))
BEGIN
-- this translates an enum's choices into a single-column table.
DECLARE subQuery TEXT;
DECLARE firstPos INT(11);
-- This gets a string like "enum('value1','value2','value3')"
SET subQuery = (SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_SCHEMA = dbName AND TABLE_NAME = tableName AND COLUMN_NAME = columnName));
-- trim off the leading "enum("
SET subQuery = SUBSTRING_INDEX(subQuery, "enum(", -1);
-- and the trailing ")"
SET subQuery = SUBSTRING_INDEX(subQuery, ")", 1);
-- replace all the "," with " UNION SELECT "
SET subQuery = REPLACE(subQuery,","," UNION SELECT ");
-- insert the first "SELECT "
SET subQuery = INSERT(subQuery,1,0,"SELECT ");
-- find the first position of "UNION"
SET firstPos = INSTR(subQuery, 'UNION');
-- insert the column name "Options" before that first "UNION"
SET subQuery = INSERT(subQuery, firstPos, 0, "AS `Options` ");
-- This is to execute the query. Until I figure out a better way.
SET @enumProcQuery = (subQuery);
PREPARE STMT FROM @enumProcQuery;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END$$
DELIMITER ;
L'exécution de cette procédure me donne par exemple :
Code : Tout sélectionner
mysql> CALL GetEnumChoiceList('mabase','telephone','tel_type');
+----------+
| Options |
+----------+
| domicile |
| portable |
| fax |
| bureau |
+----------+
4 rows in set (0.09 sec)
Ok, maintenant, resterait à faire la même chose en PHP5 : j'ai fait plusieurs essais, le dernier en date m'affiche en guise de résultat :
Warning: mysqli_stmt::bind_result() [function.mysqli-stmt-bind-result.php]: Number of bind variables doesn't match number of fields in prepared statement. in C:\www\ApprentissagePHP\MySQLI\procedureStockee.php on line 37
Voici pour illustrer le code utilisé :
<?php
$schema = "*********";
$colonne = "tel_type";
$sql = "CALL GetEnumChoiceList('mabase', 'telephone',?)";
$mysqli = new mysqli("localhost", "*****", "*****", $schema);
/* Vérification de la connexion */
if (mysqli_connect_errno())
{
printf("La connexion a échoué : %s\n", mysqli_connect_error());
}
else
{
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $colonne);
$stmt->execute();
/* Lecture des valeurs */
$stmt->bind_result($col_retour);
while(false != $stmt->fetch())
{
printf("Option ". $colonne ."; Valeur : %s;", $col_retour);
}
$stmt->close();
/* Fermeture de la connexion */
$mysqli->close();
}
?>
Une piste ? J'aimerais bien faire afficher le résultat avec un genre de var_dump() pour comprendre l'histoire du nombre de colonnes non correspondant du message d'erreur, mais je ne suis pas familier avec cette méthode objet mysqli

Salut tout le monde,
je me heurte à un irritant. J'ai trouvé dans la doc de MySQL un exemple tout à fait pratique de procédure stockée pour lister les options d'une colonne de type ENUM. En ligne de commande, ça fonctionne parfaitement bien.
Pour illustrer et surtout pour ceux que ça intéresse, voici dans un premier temps le code de cette procédure :
[code]DELIMITER $$
CREATE PROCEDURE `GetEnumChoiceList`(IN dbName VARCHAR(80), IN tableName VARCHAR(80), IN columnName VARCHAR(80))
BEGIN
-- this translates an enum's choices into a single-column table.
DECLARE subQuery TEXT;
DECLARE firstPos INT(11);
-- This gets a string like "enum('value1','value2','value3')"
SET subQuery = (SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_SCHEMA = dbName AND TABLE_NAME = tableName AND COLUMN_NAME = columnName));
-- trim off the leading "enum("
SET subQuery = SUBSTRING_INDEX(subQuery, "enum(", -1);
-- and the trailing ")"
SET subQuery = SUBSTRING_INDEX(subQuery, ")", 1);
-- replace all the "," with " UNION SELECT "
SET subQuery = REPLACE(subQuery,","," UNION SELECT ");
-- insert the first "SELECT "
SET subQuery = INSERT(subQuery,1,0,"SELECT ");
-- find the first position of "UNION"
SET firstPos = INSTR(subQuery, 'UNION');
-- insert the column name "Options" before that first "UNION"
SET subQuery = INSERT(subQuery, firstPos, 0, "AS `Options` ");
-- This is to execute the query. Until I figure out a better way.
SET @enumProcQuery = (subQuery);
PREPARE STMT FROM @enumProcQuery;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END$$
DELIMITER ;[/code]
L'exécution de cette procédure me donne par exemple :
[code]mysql> CALL GetEnumChoiceList('mabase','telephone','tel_type');
+----------+
| Options |
+----------+
| domicile |
| portable |
| fax |
| bureau |
+----------+
4 rows in set (0.09 sec)[/code]
Ok, maintenant, resterait à faire la même chose en PHP5 : j'ai fait plusieurs essais, le dernier en date m'affiche en guise de résultat :
[quote]
Warning: mysqli_stmt::bind_result() [function.mysqli-stmt-bind-result.php]: Number of bind variables doesn't match number of fields in prepared statement. in C:\www\ApprentissagePHP\MySQLI\procedureStockee.php on line 37[/quote]
Voici pour illustrer le code utilisé :
[php]<?php
$schema = "*********";
$colonne = "tel_type";
$sql = "CALL GetEnumChoiceList('mabase', 'telephone',?)";
$mysqli = new mysqli("localhost", "*****", "*****", $schema);
/* Vérification de la connexion */
if (mysqli_connect_errno())
{
printf("La connexion a échoué : %s\n", mysqli_connect_error());
}
else
{
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s", $colonne);
$stmt->execute();
/* Lecture des valeurs */
$stmt->bind_result($col_retour);
while(false != $stmt->fetch())
{
printf("Option ". $colonne ."; Valeur : %s;", $col_retour);
}
$stmt->close();
/* Fermeture de la connexion */
$mysqli->close();
}
?>[/php]
Une piste ? J'aimerais bien faire afficher le résultat avec un genre de var_dump() pour comprendre l'histoire du nombre de colonnes non correspondant du message d'erreur, mais je ne suis pas familier avec cette méthode objet mysqli :oops: