存储过程,MySQL和PHP

时间:2020-03-06 14:34:28  来源:igfitidea点击:

这个问题是一个相当开放的问题。我已经将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";