PHP PDO与SQL Server和预处理语句

6

已经有很多类似的问题被发布了。然而,我还没有找到让这段代码工作的方法。

我正在将一个PHP代码库从本机MSSQL查询更新为使用PDO,具体来说是使用ODBC。这里是旧代码和我尝试的两个变化。

旧样式:可行,这会产生预期结果的数组。

$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);

使用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);

生成许多预期结果的数组。但是任何尝试绑定参数都会导致$results成为空数组。没有报错信息。

$sp= $db->prepare("EXEC procedure :param");
$sp->bindParam(':param', $param, PDO::PARAM_INT);

这会导致结果集为空,并且没有报告任何错误。
使用ODBC "SQL"似乎根本不起作用:
$pdo = new PDO($'dblib:host=connection', 'user', 'password');
$pdo->query('use database');

$sp= $db->prepare("CALL procedure");
$sp->execute();

while ($row = $sp->fetch(PDO::FETCH_BOUND)) $results[] = $row; 
$sp->closeCursor();
var_dump(results);

$results为空;无论是否带参数,它似乎都不起作用。

系统详情:在已安装unixodbc和freetds的Ubuntu Trusty(14)上运行PHP 5.5.9。

我真的很需要一个能够使用MSSQL调用存储过程并绑定参数的PHP PDO工作示例。


请提供完整的上下文,我不能翻译没有背景信息的内容。 - Your Common Sense
SQL Server的参数前缀是@,而不是:修改后的第二个代码片段可能会抛出一个从未被检查的错误。第三个代码片段根本没有绑定任何参数。 - Panagiotis Kanavos
你必须升级到PHP >5.6,因为PDO ODBC中存在已知的错误,会阻止64位系统上的参数绑定。 - Jeff Puckett
1
当然,可以查看这个链接:https://dev59.com/sVoT5IYBdhLWcg3wtBRz#38327719。 - Jeff Puckett
@Aleksey Ratnikov,谢谢。我以前的印象(来自php文档)是设置PDO::ERRMODE_EXCEPTION会在出现错误时抛出异常。但在我的测试中没有任何区别,这就是为什么它不在示例代码中的原因。我将尝试检查返回值。 - Steve E.
显示剩余7条评论
2个回答

3

好的,这非常有帮助。我可以使用ODBC DSN连接并使用该语法调用过程。但是,我仍然无法使绑定参数起作用。我已经打开了ODBC跟踪,并将看看明天是否会给出更多线索。 - Steve E.
我没有看到任何使用绑定参数的PHP代码,因此我无法在那里提供任何有用的评论... - TallTed
谢谢。虽然如果你在问题中搜索“bind”,会有一些代码示例。也许我完全弄错了,还有其他的方法。 - Steve E.
更明确地说,我没有看到您使用绑定参数的PDO+ODBC代码,这应该与其他所有代码有些不同。 - TallTed

3
尝试这个...
$result = array();

$sp= $db->prepare("EXECUTE dbo.procedure :param");
$sp->bindParam(":param", $param, PDO::PARAM_INT);
$sp->execute();

$result = $sp->fetchall(PDO::FETCH_OBJ);

没问题。我还得把连接的 DSN 从 dblib 改成 '$pdo = new PDO('odbc=connection', 'user', 'password');'。 - Steve E.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接