Il s'avère que c'est un bug qui dure depuis longtemps... depuis 2005 !
Voici le rapport de bogue original :2005 à 2013 . Et voici le nouveau rapport de bogue :De 2013 à aujourd'hui .
Il existe différentes approches pour obtenir la réponse, j'en ai trouvé une et je la démontre...
Le "truc" consiste à obtenir la sortie d'une procédure "mysql". Il s'agit d'un processus en « deux étapes ».
-
La première partie consiste à exécuter la procédure avec vos entrées et à lui indiquer également dans quelles variables MYSQL stocker le résultat.
-
Ensuite, vous exécutez une requête distincte pour 'sélectionner' ces variables 'mysql'.
Il est décrit assez clairement ici :php-calling-mysql-stored-procedures
Mise à jour (janvier 2017) :
Voici un exemple montrant l'utilisation de variables pour les paramètres de procédure Mysql 'IN', 'INOUT' et 'OUT'.
Avant de commencer, voici quelques conseils :
- Lors du développement :exécutez PDO en "mode émulation", car il est plus fiable pour déterminer les erreurs dans l'appel de procédure.
- Liez uniquement les variables PHP aux paramètres "IN" de la procédure.
Vous obtiendrez des erreurs d'exécution vraiment étranges lorsque vous essayez de lier des variables aux paramètres INOUT et OUT.
Comme d'habitude, j'ai tendance à fournir plus de commentaires que nécessaire ;-/
Environnement d'exécution (XAMPP) :
- PHP : 5.4.4
- MySQL :5.5.16
Code source :
Code SQL :
CREATE PROCEDURE `demoSpInOutSqlVars`(IN pInput_Param INT, /* PHP Variable will bind to this*/
/* --- */
INOUT pInOut_Param INT, /* contains name of the SQL User variable that will be read and set by mysql */
OUT pOut_Param INT) /* contains name of the SQL User variable that will be set by mysql */
BEGIN
/*
* Pass the full names of SQL User Variable for these parameters. e.g. '@varInOutParam'
* These 'SQL user variables names' are the variables that Mysql will use for:
* 1) finding values
* 2) storing results
*
* It is similar to 'variable variables' in PHP.
*/
SET pInOut_Param := ABS(pInput_Param) + ABS(pInOut_Param); /* always positive sum */
SET pOut_Param := ABS(pInput_Param) * -3; /* always negative * 3 */
END$$
Code PHP :
Connexion à la base de données :
$db = appDIC('getDbConnection', 'default'); // get the default db connection
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
Remarque :La sortie est la même avec EMULATE_PREPARES
=faux.
Définissez toutes les variables PHP qui seront utilisées :
$phpInParam = 5;
$phpInOutParam = 404; /* PHP InOut variable ==> read and should be changed */
$phpOutParam = null; /* PHP Out variable ==> should be changed */
Définissez et préparez l'appel de procédure SQL :
$sql = "call demoSpInOut(:phpInParam,
@varInOutParam, /* mysql variable name will be read and updated */
@varOutParam)"; /* mysql variable name that will be written to */
$stmt = $db->prepare($sql);
Liez les variables PHP et définissez les variables SQL :
-
1) lier les variables PHP
$stmt->bindParam(':phpInParam', $phpInParam, PDO::PARAM_INT);
-
2) Définissez les variables SQL utilisateur INOUT
$db->exec("SET @varInOutParam =$phpInOutParam"); // Ceci est sûr car il définit simplement la valeur dans la variable MySql.
Exécutez la procédure :
$allOk = $stmt->execute();
Récupérez les variables SQL dans les variables PHP :
$sql = "SELECT @varInOutParam AS phpInOutParam,
@varOutParam AS phpOutParam
FROM dual";
$results = current($db->query($sql)->fetchAll());
$phpInOutParam = $results['phpInOutParam'];
$phpOutParam = $results['phpOutParam'];
Remarque :ce n'est peut-être pas le meilleur moyen ;-/
Afficher les variables PHP
"$phpInParam:" => "5"
"$phpInOutParam:" => "409"
"$phpOutParam:" => "-15"