使用MSSQL驱动的PDO如何获取输出参数?

22
当您使用 PDOMSSQL驱动程序 时,实际上使用 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)。
因此,4.2 不是一个选择。

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驱动程序调用存储过程?


2
我记得需要消耗结果集才能分配输出。你尝试过在调用execute之后,使用$stmt->fetchAll();来获取结果集吗:mssql_execute($stmt); $stmt->fetchAll(); ... ,但在使用$value的值之前。 - Gavin
1
很遗憾,它不起作用。 - Nick Bondarenko
1
我已经找到了正确的语法。请看我的答案。 - Marco Marsala
1
https://dev59.com/ZmYr5IYBdhLWcg3wy9OA#32224294 - Marco Marsala
2个回答

2

我第一次回答时可能错过了FreeTDS,或者这个问题已经更新了。无论哪种情况...

FreeTDS不支持MSSQL Server 7 SP3或更高版本的输出参数。这是由于SQL Server所做的更改造成的。

---以下是旧回复---

我知道这不完全符合你的要求。
我查看了一些旧文件,找到了我链接到MSSQL的唯一一次,并提取了这个信息。

$con = mssql_connect($db['host'], $db['user'], $db['pass']);
mssql_select_db($db['database'], $con);//Select DB
$result = mssql_query("my_Procedure_Name ".$propertyOne.", ".$propertyTwo."");

我希望您能从中获得帮助。

-5

试试这个

 try {
    $hostname = "myhost";
    $port = 10060;
    $dbname = "tempdb";
    $username = "dbuser";
    $pw = "password";
    $dbh = new PDO ("dblib:host=$hostname:$port;dbname=$dbname","$username","$pw");
  } catch (PDOException $e) {
    echo "Failed to get DB handle: " . $e->getMessage() . "\n";
    exit;
  }
  $stmt = $dbh->prepare("select name from master..sysdatabases where name = db_name()");
  $stmt->execute();
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
  unset($dbh); unset($stmt);

4
这与问题毫无关联。 - Ben Jaguar Marshall

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