当您使用PDO与MSSQL的驱动程序,你实际使用freetds的低级别的驱动程序.执行存储过程有一些不同的方法 - 语言查询和RPC调用.
FreeTDS还支持TDS协议版本4.2和7.x. 它们之间的主要区别之一是存储过程调用的行为.Microsoft将协议4.2中的行为更改为7.0,而不是从语言查询返回输出参数.语言查询主要将文本查询发送到包装到TDS包中的服务器.
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'Hello!';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
$stmt->execute();
print "The output is $value\n";
Run Code Online (Sandbox Code Playgroud)
实际上你发送的东西就像"EXEC sp_takes ....".如果您使用MSSQL运行上面的示例,您将获得TDS7.х中的空输出参数和4.2的预期结果.为什么我们不能使用4.2并且开心?它有很多局限性:
prepared statements不支持动态查询(也称为).所以,4.2不是变种.
$stmt = mssql_init('sp_takes_string_returns_string');
$value = 'Hello!';
mssql_bind($stmt, 1, $value, SQLVARCHAR, true, false, 4000);
mssql_execute($stmt);
print "The output is $value\n";
Run Code Online (Sandbox Code Playgroud)
使用上面的示例和php中的本机mssql扩展,您可以使用TDS 7.2获得正确的结果.实际上,您使用该代码发送二进制RPC数据包.
是否有任何方法可以使用PDO和MSSQL驱动程序对存储过程进行RPC调用?
我用谷歌搜索了,但没有提出任何我可以解决的问题.
使用存储过程的性能提升是否显着?
我是否仍然希望将预准备语句与存储过程一起使用,或者它通常是一个还是另一个?
我可以通过PHPMyAdmin创建存储过程并从那里管理它们吗?
对于像这样简单的事情,存储过程会是什么样子 -
SELECT * FROM table a
INNER JOIN otherTable b
ON a.join_id=b.join_id
WHERE someVar = :boundParam
Run Code Online (Sandbox Code Playgroud)
以及PHP如何工作(PDO)来调用它并绑定其参数?
我正在使用返回错误代码的SQL Server存储过程; 这是SP的一个非常简单的片段.
DECLARE @ret int
BEGIN
SET @ret = 1
RETURN @ret
END
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令获取mssql扩展的返回值:
mssql_bind($proc, "RETVAL", &$return, SQLINT2);
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚如何在PDO中访问返回值; 我不想使用OUT参数,因为已经编写了很多这些存储过程.这是我当前如何在PHP中调用该过程的示例.
$stmt = $this->db->prepare("EXECUTE usp_myproc ?, ?");
$stmt->bindParam(1, 'mystr', PDO::PARAM_STR);
$stmt->bindParam(2, 'mystr2', PDO::PARAM_STR);
$rs = $stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
Run Code Online (Sandbox Code Playgroud) 已经发布了许多类似的问题.但是我还没有找到让这段代码正常工作的方法.
我正在从本机MSSQL查询更新PHP代码库以使用PDO,特别是使用ODBC.这是旧代码和我尝试过的两种变体.
旧样式: Works,这会产生一系列预期结果.
$db = mssql_connect('connection', 'user', 'password');
mssql_select_db('database', $db);
$sp = mssql_init('procedure', $db);
$param=1;
$results=[];
mssql_bind($sp,'@param',$param,SQLINT4,FALSE,FALSE);
$spRes = mssql_execute($sp);
while ($row = mssql_fetch_array($spRes, MSSQL_ASSOC)) $results[] = $row;
mssql_free_statement($sp);
var_dump(results);
Run Code Online (Sandbox Code Playgroud)
使用带有PDO的T-SQL几乎可以工作:只要我不尝试绑定任何参数,我就会得到结果.
$pdo = new PDO($'dblib:host=connection', 'user', 'password');
$pdo->query('use database');
$sp= $db->prepare("EXEC procedure");
$sp->execute();
while ($row = $sp->fetch(PDO::FETCH_BOUND)) $results[] = $row;
$sp->closeCursor();
var_dump(results);
Run Code Online (Sandbox Code Playgroud)
产生许多预期结果的数组.但是,任何绑定参数的尝试都会导致为$results空数组.没有报告错误.
$sp= $db->prepare("EXEC procedure :param");
$sp->bindParam(':param', $param, PDO::PARAM_INT);
Run Code Online (Sandbox Code Playgroud)
这会导致结果集为空,并且不会报告错误.
使用ODBC"SQL"似乎根本不起作用:
$pdo = new PDO($'dblib:host=connection', 'user', 'password');
$pdo->query('use database');
$sp= $db->prepare("CALL procedure");
$sp->execute();
while …Run Code Online (Sandbox Code Playgroud) 我刚开始使用PHP PDO和MySQL存储过程,我有如何从过程调用中获取OUT参数的问题.我查看了许多类似的stackoverflow主题,但遗憾的是我无法找到解决问题的方法:|
以下是详细信息:
该过程采用1个输入参数,并有2个强制输出参数,并返回结果状态.
这就是我所说的:
$input = 5;
$mydb = new PDO("mysql:host=localhost;dbname=mydb", "user", "pass");
$proc = $mydb->prepare("CALL proc_name($input, @o_code, @o_message)");
$proc->execute();
Run Code Online (Sandbox Code Playgroud)
该过程在@o_code参数中返回INT,在@o_message参数中返回STRING.如果从CLI调用它,并且在调用之后我在CLI中编写
select @o_code, @o_message;
Run Code Online (Sandbox Code Playgroud)
一切都很好,就是我能够看到这些OUT参数中返回的值.但是我不能用PHP代码做到这一点 - 出于某种原因我总是得到FALSE结果.该程序正确地完成了它的工作,但我无法得到它的结果.
在我进行上述调用之后,我尝试了以下方法来获取值:
$output = $proc->fetch(PDO::FETCH_ASSOC); // also with PDO:FETCH_OBJ
$output = $mydb->query("select @o_code, @o_message");
$output = $mydb->query("select @o_code, @o_message")->fetch();
$output = $mydb->query("select @o_code, @o_message")->fetchColumn();
$output = $mydb->query("select @o_code, @o_message")->fetchAll();
Run Code Online (Sandbox Code Playgroud)
但是这些都不会返回任何与NULL或FALSE不同的结果.我也试过bindParam,但仍然无法使其工作.
感谢您在这个问题上的任何帮助和美好的一天!
-----编辑-----
这是我尝试使用bindParam的代码,它仍然不起作用:
$input = 5;
$proc = $mydb->prepare("CALL proc_name(?, ?, ?)");
$proc->bindParam(1, $input, PDO::PARAM_INT);
$proc->bindParam(2, $code, PDO::PARAM_INT);
$proc->bindParam(3, $message, PDO::PARAM_STR);
$proc->execute();
var_dump($code, …Run Code Online (Sandbox Code Playgroud) 问题是一个相当开放的问题.我已经使用存储过程与MS SQLServer一段时间使用经典的ASP和ASP.net并且非常喜欢它们.
我有一个小的业余爱好项目我正在研究,由于各种原因已经走了LAMP路线.使用MySQL和PHP5的存储过程的任何提示/技巧/陷阱或良好的起点?我的MySQL版本支持存储过程.