【问题标题】:sqlsrv_num_rows Not Returning Any Valuesqlsrv_num_rows 不返回任何值
【发布时间】:2014-05-19 15:23:25
【问题描述】:

我正在尝试获取查询中返回的行数。循环遍历结果的 while 循环有效,但由于某种原因 sqlsrv_num_rows 不返回任何值:

$result = "SELECT * from dtable WHERE id2 = 'apple'";
$query = sqlsrv_query($conn, $result);

$row_count = sqlsrv_num_rows($query);
echo $row_count;

while($row = sqlsrv_fetch_array($query))
{
      echo 'yes';
}

谢谢。

【问题讨论】:

  • 为什么不使用创建结果数组并使用count() 来计算返回的行。只是一个想法。

标签: php sqlsrv


【解决方案1】:

这是因为sqlsrv_query()默认使用SQLSRV_CURSOR_FORWARD游标类型。但是,为了从 sqlsrv_num_rows() 获得结果,您应该选择以下光标类型之一:

  • SQLSRV_CURSOR_STATIC
  • SQLSRV_CURSOR_KEYSET
  • SQLSRV_CURSOR_CLIENT_BUFFERED

欲了解更多信息,请查看:Cursor Types (SQLSRV Driver)

总之,如果您使用如下查询:

$query = sqlsrv_query($conn, $result, array(), array( "Scrollable" => 'static' ));

你会得到结果:

$row_count = sqlsrv_num_rows($query);

【讨论】:

    【解决方案2】:

    我同意杰克的观点。 I count(*) 是一种快速获取行数的方法,但是,您可能需要进行聚集索引扫描。对于小型数据集,这不是问题。

    另一方面,您可以使用系统目录视图。但是,这些会根据某个后台线程进行更新。对于多 TB 数据集,目录查找可能会更快。

    根据系统事件,计数可能准确也可能不准确。

    http://sqlblog.com/blogs/kalen_delaney/archive/2009/12/07/how-many-rows.aspx

    这完全取决于您需要的准确度。如果是账本数据,那么非常准确。如果是预测数据,可能不太准确。

    我建议使用 RCSI 而不是默认的 READ COMMITTED 以获得更好的时间点计数。这是使用 SELECT COUNT(*) FROM [TABLE] 语法。

    http://www.sqlpass.org/summit/2013/Sessions/SessionDetails.aspx?sid=4730

    Randy Knight 去年对此进行了精彩的介绍。

    您还可以查看我的隔离演示文稿,其中的代码表明 READ COMMITTED 可能不准确。

    http://craftydba.com/?page_id=880

    下面列出了三种解决方案。

    祝你好运

    J

    -- Show time & i/o
    SET STATISTICS TIME ON
    SET STATISTICS IO ON
    GO
    
    -- Remove clean buffers & clear plan cache
    CHECKPOINT 
    DBCC DROPCLEANBUFFERS 
    DBCC FREEPROCCACHE
    GO
    
    -- test database
    use adventureworks2012
    go
    
    
    -- traverse the table
    select count(*) as 'rows' from person.address
    go
    

    /*

    SQL Server 解析和编译时间: CPU 时间 = 0 毫秒,经过的时间 = 0 毫秒。

    (1 行受影响) 表“地址”。扫描计数 1,逻辑读取 36,物理读取 1,预读读取 34,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

    SQL Server 执行时间: CPU 时间 = 15 毫秒,运行时间 = 26 毫秒。

    */

    -- Look at sysindexes
    select o.name as 'Table', max(i.rows) 'Rows'
    from sysobjects o join sysindexes i
    on o.id = i.id
    where 
    (i.indid = 1 or i.indid = 0) and
    o.type = 'U' and
    o.name = 'Address'
    group by o.name
    go
    

    /*

    SQL Server 解析和编译时间: CPU 时间 = 15 毫秒,运行时间 = 132 毫秒。

    (1 行受影响) 表 'sysidxstats'。扫描计数 1,逻辑读取 2,物理读取 2,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表'sysschobjs'。扫描计数 1,逻辑读取 6,物理读取 3,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

    SQL Server 执行时间: CPU 时间 = 0 毫秒,运行时间 = 36 毫秒。

    */

    -- Look at sys.partitions
    SELECT max(rows) as 'Rows'  FROM sys.partitions 
    WHERE object_id = object_id('Person.Address');
    

    /*

    SQL Server 解析和编译时间: CPU 时间 = 16 毫秒,运行时间 = 104 毫秒。

    (1 行受影响) 表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表 'sysidxstats'。扫描计数 1,逻辑读取 10,物理读取 2,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表'sysschobjs'。扫描计数 0,逻辑读取 4,物理读取 2,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表 'sysrowsets'。扫描计数 1,逻辑读取 6,物理读取 1,预读读取 24,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

    SQL Server 执行时间: CPU 时间 = 0 毫秒,经过的时间 = 34 毫秒。

    */

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      • 2019-05-22
      相关资源
      最近更新 更多