存储过程,MySQL和PHP
这个问题是一个相当开放的问题。我已经将MS SQLServer的存储过程与经典的ASP和ASP.net一起使用了一段时间,并且非常喜欢它们。
我有一个正在从事的小型业余项目,出于各种原因,该项目走了LAMP路线。在MySQL和PHP5中使用存储过程有任何提示/技巧/陷阱或者良好的起点吗?我的MySQL版本支持存储过程。
解决方案
我们将需要使用MySQLI(MySQL改进的扩展)来调用存储过程。调用SP的方法如下:
$mysqli = new MySQLI(user,pass,db); $result = $mysqli->query("CALL sp_mysp()");
使用SP时,我们需要关闭第一个结果集,否则会收到错误消息。这是更多信息:
http://blog.rvdavid.net/using-stored-procedures-mysqli-in-php-5/ (broken link)
另外,我们可以使用Prepared Statements,我发现它很简单:
$stmt = $mysqli->prepare("SELECT Phone FROM MyTable WHERE Name=?"); $stmt->bind_param("s", $myName); $stmt->execute();
MySQLI文档:http://no.php.net/manual/zh/book.mysqli.php
忘了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";
使用mysqli或者PDO在MySQL 5中调用存储过程实际上并不是强制性的。我们可以使用旧的mysql_函数很好地调用它们。我们唯一不能做的就是返回多个结果集。
我发现无论如何返回多个结果集都容易出错。在某些情况下它确实可以工作,但前提是应用程序必须记住全部使用它们,否则连接将处于断开状态。
我一直在使用ADODB,这对于抽象实际命令以使其在不同的SQL Server(例如mysql到mssql)之间可移植来说是一件很棒的事情。但是,似乎不直接支持存储过程。这意味着,我已经像正常查询一样运行了SQL查询,但是要"调用" SP。
查询示例:
$query = "Call HeatMatchInsert('$mMatch', '$mOpponent', '$mDate', $mPlayers, $mRound, '$mMap', '$mServer', '$mPassword', '$mGame', $mSeason, $mMatchType)";
这不考虑返回的数据,这一点很重要。我猜想这将通过设置@Var来完成,我们可以选择自己作为返回值@Variable。
简而言之,尽管制作第一个基于php存储过程的Web应用程序非常困难(有关mssql的文档非常丰富,但事实并非如此),但由于分离而使更改很容易进行之后,这很不错。
@michal kralik不幸的是,PDO使用的MySQL C API有一个错误,这意味着以某些版本的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";