2008-09-23 3 views
4

Вопрос довольно открытый. Я использую хранимые процедуры с MS SQLServer в течение некоторого времени с классическими ASP и ASP.net и люблю их, много.Хранимые процедуры, MySQL и PHP

У меня есть небольшой проект хобби, над которым я работаю, и по разным причинам пошел по маршруту ЛАМПЫ. Любые подсказки/трюки/ловушки или хорошие отправные точки для использования хранимых процедур с MySQL и PHP5? Моя версия MySQL поддерживает хранимые процедуры.

+0

Можете ли вы объяснить, почему вы хотите использовать хранимые процедуры? Обычная мудрость гласит: «Используйте хранимые процедуры только тогда, когда это необходимо», поэтому мне нужно понять вашу мотивацию ответить. – 2008-09-23 02:23:09

+0

@Alex Мне нравится возможность извлекать несколько наборов результатов с точки зрения выбора (сокращение вызовов в режиме db), параметризации, чтобы уменьшить шансы SQL-инъекции. Также с помощью SQL Server Stored Procs пути выполнения оптимизируются SQL Server. Также я использую этот маленький хобби-проект как инструмент обучения. – 2008-09-23 22:19:03

+0

@ Ale.continued! Я также получаю лучшее повторное использование из хранимых процедур. Если у меня есть функция db, которая часто используется, мне нужно только обновить ее в одном месте. Я понимаю, что это также можно обрабатывать на уровне PHP с помощью функций/классов. Я не нашел причин не использовать Stores Procs с MSSQL & ASP/.net – 2008-09-23 22:31:53

ответ

5

Забудьте о mysqli, это гораздо сложнее в использовании, чем PDO, и должны быть уже удалены. Это правда, что он ввел огромные улучшения по сравнению с mysql, но для достижения такого же эффекта в mysqli иногда требуется огромное усилие над PDO, то есть ассоциативным fetchAll.

Вместо этого взгляните на PDO, в частности prepared statements and stored procedures.

$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"; 
2

Чтобы вызвать хранимые процедуры, вам необходимо использовать MySQLI (MySQL Improved Extension). Вот как бы вы назвать SP:

$mysqli = new MySQLI(user,pass,db); 

$result = $mysqli->query("CALL sp_mysp()"); 

При использовании ПЛов вам необходимо тесное первый ResultSet или вы получите сообщение об ошибке. Вот еще информация:

http://blog.rvdavid.net/using-stored-procedures-mysqli-in-php-5/ (broken link)

В качестве альтернативы, вы можете использовать Подготовленные заявления, которые я нахожу очень прямолинейно:

$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

2

Это на самом деле не обязательно использовать MySQLi или PDO для вызова хранимых процедур в MySQL 5. Вы можете называть их просто отлично со старыми функциями mysql_. Единственное, что вы не можете сделать, это вернуть несколько наборов результатов.

Я обнаружил, что возвращение нескольких наборов результатов в любом случае подвержено некоторой ошибке; он работает в некоторых случаях, но только в том случае, если приложение помнит, что потребляет их все, в противном случае соединение остается в разбитом состоянии.

0

Я использую ADODB, что отлично подходит для абстрагирования реальных команд, чтобы сделать его переносимым между различными серверами SQL (т.е. mysql to mssql). Однако Хранимые процедуры не поддерживаются напрямую. Это означает, что я запускал SQL-запрос, как если бы он был нормальным, но «вызывал» SP. Пример запроса:

$query = "Call HeatMatchInsert('$mMatch', '$mOpponent', '$mDate', $mPlayers, $mRound, '$mMap', '$mServer', '$mPassword', '$mGame', $mSeason, $mMatchType)"; 

Это без учета возвращенных данных, что важно. Я предполагаю, что это будет сделано, установив @Var, чтобы вы могли выбрать себя как return @Variable.

Чтобы быть абстрактным, хотя создание первого веб-приложения, основанного на PHP-хранимой процедуре, было очень трудным для работы (mssql очень хорошо документирован, это не так). Это здорово после его завершения - изменения очень легко сделать к разделению.

6

@michal Кралика - к сожалению, есть ошибка с API MySQL C, который использует PDO, что означает, что для запуска кода, как описано выше с некоторыми версиями результатов MySQL в случае ошибки:

"Syntax error or access violation: 1414 OUT or INOUT argument $parameter_number for routine $procedure_name is not a variable or NEW pseudo-variable".

Вы можете увидеть ошибку отчет по 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";