【发布时间】:2013-12-27 17:23:50
【问题描述】:
当您将PDO 与MSSQL driver 一起使用时,您实际上将FreeTDS 用作低级驱动程序。有一些不同的方法可以执行存储过程 - 语言查询和RPC call。
FreeTDS 还支持 TDS 协议版本 4.2 和 7.x。它们之间的主要区别之一是存储过程调用的行为。 Microsoft 将行为从协议 4.2 更改为 7.0 不从语言查询返回输出参数。 语言查询主要是将文本查询打包成一个 TDS 数据包发送到服务器。
使用 PDO 的语言查询示例(来自 php.net)
$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";
实际上,您发送的内容类似于“EXEC sp_takes....”。如果您使用 MSSQL 运行上面的示例,您将在 TDS 7.х 中获得空输出参数,并在 4.2 中获得预期结果。为什么我们不能使用 4.2 并快乐?它有很多limitations:
- 当然只有 ASCII。
- 不支持 RPC 和 BCP。
- varchar 字段限制为 255 个字符。如果您的表格定义了较长的字段,它们将被截断。
- 不支持动态查询(也称为
prepared statements)。
所以,4.2 不是变体。
RPC 调用示例(来自php.net odbtp extension)
$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";
在 php 中使用上面带有本机 mssql 扩展的示例,您在 TDS 7.2 中得到了正确的结果。实际上,您使用该代码发送二进制 RPC 数据包。
问题
有什么方法可以通过 PDO 和 MSSQL 驱动对存储过程进行 RPC 调用?
【问题讨论】:
-
我记得需要使用结果集来分配输出。您是否尝试过调用 $stmt->fetchAll();在您调用执行之后:
mssql_execute($stmt); $stmt->fetchAll(); ...,但在使用 $value 的值之前。 -
不幸的是不能工作。
-
我找到了正确的语法。看我的回答
标签: php sql-server pdo freetds