【问题标题】:PDO row count - num_rows equivalentPDO 行数 - 相当于 num_rows
【发布时间】:2023-03-21 06:58:01
【问题描述】:

我正在将 PHP 代码从 mysql 移动到 ms sql 服务器。 这将执行我的查询:

  $r = $db_conn->prepare($sql);
  $r->execute();

在开始处理之前,我需要计算返回的行数。

旧代码:

$r->num_rows;

新代码:

$rows  = $r->fetchAll(PDO::FETCH_ASSOC);
$rcount = count($rows);

一切都好,但是当我尝试从第一行访问值时,我什么也没得到...

try {
    $row = $r->fetch(PDO::FETCH_ASSOC);
} catch (Exception $ex) {   
    return 0;
}   

计数后我需要重新指向记录集中的第一行,我怎样才能做到这一点而不必再次重新查询数据库?

我是 PHP 新手,很抱歉这个愚蠢且可能很明显的问题。 提前致谢。

【问题讨论】:

  • php.net/manual/en/pdostatement.rowcount.php,虽然对于selects,不确定它是否适用于sql-server。它不适用于mysql
  • 您好 - 谢谢,但已经尝试过了,也不适用于 sql server 选择。如果是这样就好了……

标签: php sql-server pdo


【解决方案1】:

PDO 中没有办法重置指针。您可以再次执行查询,但鉴于您已经通过调用fetchAll 获取了所有数据,这是一种浪费。相反,要访问数据,只需遍历 $rows 数组,例如

foreach ($rows as $row) {
    // do something
}

请注意,如果您预计 fetch 会出现异常,那么您可能也会在 fetchAll 上遇到异常,因此您应该将对 fetchAll 的调用包装在 try/catch 块中:

try {
    $rows = $r->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $ex) {   
    return 0;
}   

【讨论】:

  • 您好,尼克,感谢您的快速回复。所以我不能再回到 $r 记录集中的第 1 行,然后再做 $r->fetch(PDO::FETCH_ASSOC);逐个?这就是我的旧代码所做的,所以我试图做尽可能少的更改。
  • @jacknomiz 不幸的是,没有。允许这样做的唯一选择是再次执行查询。
【解决方案2】:

如果您使用PHP Driver for SQL Server,一种可能的方法是使用PDOStatement::rowCountclient-side cursor。这种类型的游标在执行查询后可以使用行计数,但这种类型的游标应该用于小型(中型)结果集。

<?php
# Connection
$server    = 'server\instance,port';
$database  = 'master';
$uid       = 'uid';
$pwd       = 'pwd';

# PDO Connection
try {
    # SQL authentication
    $conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
    # Windows authentication
    #$conn = new PDO("sqlsrv:server=$server;Database=$database");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
    die( "Error connecting to SQL Server".$e->getMessage());
}

# Client-side cursor
try {
    $options = array(
        PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, 
        PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED
    );
    $stmt = $conn->prepare("SELECT * FROM master.sys.server_principals", $options);
    $stmt->execute();
    echo 'Row count: '.$stmt->rowCount().'<br>';
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ){
        echo 'Login name: '.$row['name'].'<br>';
    }    
} catch( PDOException $e ) {
    die( "Error executing query".$e->getMessage() );
}

# End
$stmt = null;
$conn = null;
?>

【讨论】:

  • 很好的尝试,但对于 sql server rowCount 不适用于选择。尼克的方法很有效,非常感谢你们俩的帮助。干杯。
  • @jacknomiz 这是一个工作示例,使用 PHP 7.1.12(32 位)、SQL Server 2012 和 pdo_sqlsrv 4.3.0+9904 进行了测试。请注意,如果您尝试调用存储过程,您可能需要将SET NOCOUNT ON 作为该过程的第一行。这将阻止 SQL Server 返回信息性消息作为结果集。谢谢。
猜你喜欢
  • 2017-07-02
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 2015-01-30
  • 1970-01-01
相关资源
最近更新 更多