Хранимые процедуры, MySQL и PHP
-
02-07-2019 - |
Вопрос
Этот вопрос довольно открытый.Я уже некоторое время использую хранимые процедуры с MS SQLServer с классическим ASP и ASP.net и мне они очень нравятся.
У меня есть небольшой хобби-проект, над которым я работаю, и по разным причинам я пошел по пути LAMP.Какие-нибудь подсказки / хитрости / ловушки или хорошие отправные точки для использования хранимых процедур с MySQL и PHP5?Моя версия MySQL поддерживает хранимые процедуры.
Решение
Забудь о mysqli
, это намного сложнее в использовании, чем PDO, и должно было быть уже удалено.Это правда, что он внес огромные улучшения по сравнению с mysql, но для достижения того же эффекта в mysqli иногда требуются огромные усилия по сравнению с PDO, т.е.ассоциативный fetchAll
.
Вместо этого взгляните на PDO, в частности подготовленные инструкции и хранимые процедуры.
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
print "procedure returned $value\n";
Другие советы
@michal kralik - к сожалению, есть ошибка в MySQL C API, который использует PDO, что означает, что выполнение вашего кода, как указано выше, с некоторыми версиями MySQL приводит к ошибке:
"Синтаксическая ошибка или нарушение доступа:1414 Аргумент OUT или INOUT $parameter_number для процедуры $procedure_name не является переменной или НОВОЙ псевдопеременной".
Вы можете ознакомиться с отчетом об ошибке на bugs.mysql.com.Это было исправлено для версий 5.5.3+ и 6.0.8+.
Чтобы обойти проблему, вам нужно было бы разделить входные и выходные параметры и использовать пользовательские переменные для сохранения результата следующим образом:
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(:in_string, @out_string)");
$stmt->bindParam(':in_string', 'hello');
// call the stored procedure
$stmt->execute();
// fetch the output
$outputArray = $this->dbh->query("select @out_string")->fetch(PDO::FETCH_ASSOC);
print "procedure returned " . $outputArray['@out_string'] . "\n";
На самом деле не обязательно использовать mysqli или PDO для вызова хранимых процедур в MySQL 5.Вы можете вызывать их просто отлично с помощью старых функций mysql_.Единственное, чего вы не можете сделать, это вернуть несколько результирующих наборов.
Я обнаружил, что возврат нескольких результирующих наборов в любом случае несколько подвержен ошибкам;в некоторых случаях это действительно работает, но только в том случае, если приложение не забывает использовать их все, в противном случае соединение остается в разорванном состоянии.
Вам нужно будет использовать MySQLI (Улучшенное расширение MySQL) для вызова хранимых процедур.Вот как вы бы назвали СП:
$mysqli = new MySQLI(user,pass,db);
$result = $mysqli->query("CALL sp_mysp()");
При использовании SPs вам необходимо закрыть первый результирующий набор, иначе вы получите сообщение об ошибке.Вот еще немного информации :
http://blog.rvdavid.net/using-stored-procedures-mysqli-in-php-5/ (неработающая ссылка)
В качестве альтернативы вы можете использовать Подготовленные заявления, что я нахожу очень прямолинейным:
$stmt = $mysqli->prepare("SELECT Phone FROM MyTable WHERE Name=?");
$stmt->bind_param("s", $myName);
$stmt->execute();
Документация MySQLI: http://no.php.net/manual/en/book.mysqli.php
Я использую ADODB, который отлично подходит для абстрагирования реальных команд, чтобы сделать его переносимым между различными серверами SQL (т. Е. с mysql на mssql).Однако хранимые процедуры, по-видимому, напрямую не поддерживаются.Это означает, что я запустил SQL-запрос, как если бы он был обычным, но для "вызова" SP.Пример запроса:
$query = "Call HeatMatchInsert('$mMatch', '$mOpponent', '$mDate', $mPlayers, $mRound, '$mMap', '$mServer', '$mPassword', '$mGame', $mSeason, $mMatchType)";
Это не учитывает возвращенные данные, что очень важно.Я предполагаю , что это было бы сделано путем установки параметра @Var , который вы можете выбрать сами в качестве возвращаемой переменной @ .
Хотя, если быть абстрактным, хотя с созданием первого веб-приложения на основе хранимых процедур php было очень сложно работать (mssql очень хорошо документирован, это нет), после его завершения это здорово - изменения очень легко вносить из-за разделения.