PDO与MSSQL驱动程序如何获取输出参数?

mis*_*ion 21 php sql-server pdo freetds

当您使用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";
Run Code Online (Sandbox Code Playgroud)

实际上你发送的东西就像"EXEC sp_takes ....".如果您使用MSSQL运行上面的示例,您将获得TDS7.х中的空输出参数和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";
Run Code Online (Sandbox Code Playgroud)

使用上面的示例和php中的本机mssql扩展,您可以使用TDS 7.2获得正确的结果.实际上,您使用该代码发送二进制RPC数据包.

是否有任何方法可以使用PDO和MSSQL驱动程序对存储过程进行RPC调用?

小智 -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);
Run Code Online (Sandbox Code Playgroud)

  • 这与问题没有任何关系。 (4认同)