当您使用
FreeTDS还支持TDS协议版本4.2和7.x。它们之间的主要区别之一是存储过程调用的行为。 Microsoft从协议4.2到7.0更改了行为,不会从语言查询中返回输出参数。语言查询主要将文本查询发送到服务器,包装成TDS数据包。
实际上,你发送了类似于 "EXEC sp_takes...." 的内容。如果你在 MSSQL 上运行上面的示例,你将在 TDS 7.х 中得到空的输出参数,并在 4.2 中得到预期结果。为什么我们不能使用 4.2 并感到高兴呢?它有很多限制:
PDO
和 MSSQL驱动程序 时,实际上使用 FreeTDS 作为底层驱动程序。有一些不同的方法来执行存储过程-语言查询和RPC调用。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 并感到高兴呢?它有很多限制:
- 仅支持 ASCII。
- 不支持 RPC 和 BCP。
- varchar 字段仅限于 255 个字符。如果你的表定义了更长的字段,它们将被截断。
- 不支持动态查询(也称为
prepared statements
)。
RPC 调用示例(来自 php.net odbtp 扩展)
$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驱动程序调用存储过程?
mssql_execute($stmt); $stmt->fetchAll(); ...
,但在使用$value的值之前。 - Gavin