Het blijkt dat dit een bug is die al heel lang aan de gang is... sinds 2005!
Hier is het originele bugrapport:2005 tot en met 2013 . En hier is het nieuwe bugrapport:Van 2013 tot heden .
Er zijn verschillende manieren om het antwoord terug te krijgen, ik heb er een gevonden en gedemonstreerd...
De 'truc' is om de uitvoer van een 'mysql'-procedure te krijgen. Het is een proces in 'twee fasen'.
-
Het eerste deel is om de procedure met uw invoer uit te voeren en ook te vertellen in welke MYSQL-variabelen het resultaat moet worden opgeslagen.
-
Vervolgens voert u een aparte query uit om die 'mysql'-variabelen te 'selecteren'.
Het wordt hier heel duidelijk beschreven:php-calling-mysql-stored-procedures
Update (jan. 2017):
Hier is een voorbeeld van het gebruik van variabelen voor 'IN', 'INOUT' en 'OUT' Mysql-procedureparameters.
Voordat we beginnen, volgen hier enkele tips:
- Bij het ontwikkelen:voer PDO uit in 'emulatiemodus', omdat dit betrouwbaarder is bij het vaststellen van fouten in de procedureaanroep.
- Alleen PHP-variabelen binden aan de procedure 'IN' parameters.
U krijgt enkele echt vreemde runtime-fouten wanneer u probeert variabelen te binden aan INOUT- en OUT-parameters.
Zoals gewoonlijk heb ik de neiging om wat meer commentaar te geven dan nodig is;-/
Runtime-omgeving (XAMPP):
- PHP:5.4.4
- Mysql:5.5.16
Broncode:
SQL-code:
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$$
PHP-code:
DB-verbinding:
$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);
Opmerking:de uitvoer is hetzelfde met EMULATE_PREPARES
=vals.
Stel alle PHP-variabelen in die zullen worden gebruikt:
$phpInParam = 5;
$phpInOutParam = 404; /* PHP InOut variable ==> read and should be changed */
$phpOutParam = null; /* PHP Out variable ==> should be changed */
Definieer en bereid de SQL-procedureaanroep voor:
$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);
Bind PHP-variabelen en stel SQL-variabelen in:
-
1) bind de PHP-variabelen
$stmt->bindParam(':phpInParam', $phpInParam, PDO::PARAM_INT);
-
2) Stel de SQL User INOUT-variabelen in
$db->exec("SET @varInOutParam =$phpInOutParam"); // Dit is veilig omdat het alleen de waarde in de MySql-variabele instelt.
Voer de procedure uit:
$allOk = $stmt->execute();
Verkrijg de SQL-variabelen in de PHP-variabelen:
$sql = "SELECT @varInOutParam AS phpInOutParam,
@varOutParam AS phpOutParam
FROM dual";
$results = current($db->query($sql)->fetchAll());
$phpInOutParam = $results['phpInOutParam'];
$phpOutParam = $results['phpOutParam'];
Opmerking:misschien niet de beste manier;-/
Geef de PHP-variabelen weer
"$phpInParam:" => "5"
"$phpInOutParam:" => "409"
"$phpOutParam:" => "-15"