Оказва се, че това е бъг, който съществува от доста време... от 2005 г.!
Ето оригиналния доклад за грешка:2005 до 2013 . А ето и новия доклад за грешки:От 2013 г. до момента .
Има различни подходи за връщане на отговора, намерих един от тях и го демонстрирах...
"Тръкът" е, че да получите изхода от процедура "mysql". Това е "двуетапен" процес.
-
Първата част е да изпълните процедурата с вашите входове, както и да й кажете в какви променливи на MYSQL да съхранява резултата.
-
След това изпълнявате отделна заявка, за да „изберете“ тези „mysql“ променливи.
Тук е описано доста ясно:php-calling-mysql-stored-procedures
Актуализация (януари 2017 г.):
Ето пример, показващ използването на променливи за параметрите на процедурата 'IN', 'INOUT' и 'OUT' на Mysql.
Преди да започнем, ето няколко съвета:
- Когато разработвате:Изпълнете PDO в „емулиран режим“, тъй като е по-надежден при определяне на грешки в извикването на процедурата.
- Свързвайте само PHP променливи с параметрите на процедурата 'IN'.
Ще получите някои наистина странни грешки по време на изпълнение, когато опитате да свържете променливи към параметри INOUT и OUT.
Както обикновено, съм склонен да предоставям доста повече коментари, отколкото се изисква;-/
Среда по време на изпълнение (XAMPP):
- PHP:5.4.4
- Mysql:5.5.16
Изходен код:
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$$
PHP код:
DB връзка:
$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);
Забележка:Резултатът е същият с EMULATE_PREPARES
=невярно.
Задайте всички PHP променливи, които ще се използват:
$phpInParam = 5;
$phpInOutParam = 404; /* PHP InOut variable ==> read and should be changed */
$phpOutParam = null; /* PHP Out variable ==> should be changed */
Дефинирайте и подгответе извикването на 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);
Свързване на PHP променливи и задаване на SQL променливи:
-
1) свържете PHP променливите
$stmt->bindParam(':phpInParam', $phpInParam, PDO::PARAM_INT);
-
2) Задайте променливите INOUT на SQL потребител
$db->exec("SET @varInOutParam =$phpInOutParam"); // Това е безопасно, тъй като просто задава стойността в променливата MySql.
Изпълнете процедурата:
$allOk = $stmt->execute();
Вземете SQL променливите в PHP променливите:
$sql = "SELECT @varInOutParam AS phpInOutParam,
@varOutParam AS phpOutParam
FROM dual";
$results = current($db->query($sql)->fetchAll());
$phpInOutParam = $results['phpInOutParam'];
$phpOutParam = $results['phpOutParam'];
Забележка:може би не е най-добрият начин;-/
Показване на PHP променливите
"$phpInParam:" => "5"
"$phpInOutParam:" => "409"
"$phpOutParam:" => "-15"