Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
存储过程、MySQL和PHP_Php_Mysql_Stored Procedures - Fatal编程技术网

存储过程、MySQL和PHP

存储过程、MySQL和PHP,php,mysql,stored-procedures,Php,Mysql,Stored Procedures,这是一个相当开放的问题。一段时间以来,我一直在用MS SQLServer和经典ASP和ASP.net使用存储过程,我非常喜欢它们 我有一个小的爱好项目,我正在工作,由于各种原因,我走了灯的路线。在MySQL和PHP5中使用存储过程有什么提示/技巧/陷阱或良好的起点吗?我的MySQL版本支持存储过程。您需要使用MySQLI(MySQL改进扩展)来调用存储过程。以下是如何调用SP: $mysqli = new MySQLI(user,pass,db); $result = $mysqli->

这是一个相当开放的问题。一段时间以来,我一直在用MS SQLServer和经典ASP和ASP.net使用存储过程,我非常喜欢它们


我有一个小的爱好项目,我正在工作,由于各种原因,我走了灯的路线。在MySQL和PHP5中使用存储过程有什么提示/技巧/陷阱或良好的起点吗?我的MySQL版本支持存储过程。

您需要使用MySQLI(MySQL改进扩展)来调用存储过程。以下是如何调用SP

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

$result = $mysqli->query("CALL sp_mysp()");
使用SPs时,需要关闭第一个结果集,否则会收到错误。以下是更多信息:

(断开的链接)

或者,您可以使用准备好的语句,我发现这非常简单:

  $stmt = $mysqli->prepare("SELECT Phone FROM MyTable WHERE Name=?");

  $stmt->bind_param("s", $myName);

  $stmt->execute();

MySQLI文档:

忘掉
MySQLI
,它比PDO更难使用,应该已经被删除了。的确,它比mysql带来了巨大的改进,但要在mysqli中实现同样的效果,有时需要在PDO上付出巨大的努力,即关联
fetchAll

相反,请看一看,特别是


实际上,在MySQL5中使用mysqli或PDO调用存储过程并不是强制性的。使用旧的mysql_uu函数可以很好地调用它们。唯一不能做的就是返回多个结果集


我发现返回多个结果集无论如何都有点容易出错;它在某些情况下确实可以工作,但只有当应用程序记得全部使用它们时,否则连接就会处于断开状态。

我一直在使用ADODB,这对于抽象实际命令是一件好事,可以使它在不同的SQL服务器(即mysql到mssql)之间进行移植。但是,似乎不直接支持存储过程。这意味着,我已经运行了一个SQL查询,就像它是一个普通的查询一样,但是要“调用”SP。 一个示例查询:

$query = "Call HeatMatchInsert('$mMatch', '$mOpponent', '$mDate', $mPlayers, $mRound,  '$mMap', '$mServer', '$mPassword', '$mGame', $mSeason, $mMatchType)";
这并不考虑返回的数据,这一点很重要。我猜这可以通过设置@Var来实现,您可以选择自己作为return@变量


抽象地说,尽管制作第一个基于php存储过程的web应用程序非常困难(mssql有很好的文档记录,但事实并非如此),完成后非常好-由于分离,更改非常容易。

@michal kralik-不幸的是,PDO使用的MySQL C API存在一个错误,这意味着在某些版本的MySQL中运行上述代码会导致错误:

“语法错误或访问冲突:例程$procedure\U name的1414 OUT或INOUT参数$parameter\U number不是变量或新的伪变量”

您可以在上看到错误报告。版本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";

您能解释一下为什么要使用存储过程吗?传统观点认为“只有在必要时才使用存储过程”,因此我需要了解您回答问题的动机。@Alex我喜欢在选择(减少db调用)和参数化方面检索多个结果集的能力,以帮助减少SQL注入的机会。此外,对于MS SQL Server,SQL Server还优化了存储过程的执行路径。我还将这个小爱好项目用作学习工具。@Alec.continued!我还可以从存储过程中获得更好的重用。如果我有一些经常使用的db功能,我只需要在一个位置进行更新。我意识到这也可以通过函数/类在PHP级别进行处理。我没有发现任何理由不使用MSSQL&ASP/.netmysqli错误的存储过程,是否应该删除?胡说八道。福鲁巴和迈克尔,你能详细说明你的立场吗?300个字符或更少!我同意“buggy”不是一个明智的选择,但我仍然相信它应该随着PDO的引入而被删除。的确,mysqli比mysql有了巨大的改进,但是为了在mysqli中实现同样的效果,有时需要在PDO上付出巨大的努力。我们需要在存储过程中使用准备好的语句吗?由于1)存储过程自动避免SQL注入,2)我看不出如何通过存储过程的链接实现SQL注入,在上面的“答案”中,要么是过时的,要么是垃圾邮件。
$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";