Okazuje się, że jest to błąd, który pojawia się od dłuższego czasu... od 2005 roku!
Oto oryginalny raport o błędzie:2005 do 2013 . A oto nowy raport o błędzie:Od 2013 do chwili obecnej .
Istnieją różne sposoby uzyskania odpowiedzi, znalazłem jedno z nich i zademonstrowałem to...
„Sztuczka” polega na tym, aby uzyskać dane wyjściowe z procedury „mysql”. Jest to proces „dwuetapowy”.
-
Pierwszą częścią jest uruchomienie procedury z danymi wejściowymi, a także wskazanie, w jakich zmiennych MYSQL ma być przechowywany wynik.
-
Następnie uruchamiasz oddzielne zapytanie, aby „wybrać” te zmienne „mysql”.
Jest to opisane dość wyraźnie tutaj:php-calling-mysql-stored-procedures
Aktualizacja (styczeń 2017):
Oto przykład pokazujący użycie zmiennych dla parametrów procedury Mysql 'IN', 'INOUT' i 'OUT'.
Zanim zaczniemy, oto kilka wskazówek:
- Podczas programowania:Uruchom PDO w „trybie emulacji”, ponieważ jest to bardziej niezawodne w określaniu błędów w wywołaniu procedury.
- Powiąż tylko zmienne PHP z parametrami procedury 'IN'.
Podczas próby wiązania zmiennych z parametrami INOUT i OUT otrzymasz naprawdę dziwne błędy w czasie wykonywania.
Jak zwykle zamieszczam więcej komentarzy niż jest to wymagane;-/
Środowisko wykonawcze (XAMPP):
- PHP:5.4.4
- MySQL:5.5.16
Kod źródłowy:
Kod 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$$
Kod PHP:
Połączenie z bazą danych:
$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);
Uwaga:dane wyjściowe są takie same jak w przypadku EMULATE_PREPARES
=fałsz.
Ustaw wszystkie zmienne PHP, które będą używane:
$phpInParam = 5;
$phpInOutParam = 404; /* PHP InOut variable ==> read and should be changed */
$phpOutParam = null; /* PHP Out variable ==> should be changed */
Zdefiniuj i przygotuj wywołanie procedury 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);
Powiąż zmienne PHP i ustaw zmienne SQL:
-
1) powiąż zmienne PHP
$stmt->bindParam(':phpInParam', $phpInParam, PDO::PARAM_INT);
-
2) Ustaw zmienne INOUT użytkownika SQL
$db->exec("USTAW @zmiennaInOutParam =$phpInOutParam"); // Jest to bezpieczne, ponieważ po prostu ustawia wartość w zmiennej MySql.
Wykonaj procedurę:
$allOk = $stmt->execute();
Pobierz zmienne SQL do zmiennych PHP:
$sql = "SELECT @varInOutParam AS phpInOutParam,
@varOutParam AS phpOutParam
FROM dual";
$results = current($db->query($sql)->fetchAll());
$phpInOutParam = $results['phpInOutParam'];
$phpOutParam = $results['phpOutParam'];
Uwaga:może nie najlepszy sposób;-/
Wyświetl zmienne PHP
"$phpInParam:" => "5"
"$phpInOutParam:" => "409"
"$phpOutParam:" => "-15"