web-dev-qa-db-ja.com

sqlsrv_num_rowsが値を返さない

クエリで返される行数を取得しようとしています。結果をループする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';
}

ありがとう。

11
user1067577

これは、sqlsrv_query()がデフォルトで_SQLSRV_CURSOR_FORWARD_カーソルタイプを使用するためです。ただし、sqlsrv_num_rows()から結果を取得するには、以下のカーソルタイプのいずれかを選択する必要があります。

  • SQLSRV_CURSOR_STATIC
  • SQLSRV_CURSOR_KEYSET
  • SQLSRV_CURSOR_CLIENT_BUFFERED

詳細については、以下を確認してください。 カーソルタイプ(SQLSRVドライバー)

結論として、次のようなクエリを使用する場合:

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

結果は次のようになります。

_$row_count = sqlsrv_num_rows($query);
_
23
alpakyol

私はジャックに同意します。 I count(*)は行数を取得する簡単な方法ですが、クラスター化インデックススキャンを実行する必要がある場合があります。小さなデータセットの場合、これは問題ではありません。

一方、システムカタログビューを使用することもできます。ただし、これらはいくつかのバックグラウンドスレッドごとに更新されます。マルチテラバイトのデータセットの場合、カタログ検索の方が速い場合があります。

システムイベントに応じて、カウントは正確な場合とそうでない場合があります。

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

それはすべてあなたがどれだけ正確である必要があるかに依存します。元帳データの場合、非常に正確です。予測データの場合、精度が低下する可能性があります。

タイムカウントをより適切に行うために、デフォルトのREADCOMMITTEDの代わりにRCSIを使用することをお勧めします。これは、SELECT COUNT(*)FROM [TABLE]構文を使用しています。

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

ランディナイトは昨年、この素晴らしいプレゼンテーションを行いました。

また、READCOMMITTEDが不正確になる可能性があることを示すコードを含む私の分離プレゼンテーションを見ることができます。

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

以下にリストされているのは3つのソリューションです。

幸運を

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行が影響を受けます)テーブル 'Worktable'。スキャンカウント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ミリ秒。

* /

0
CRAFTY DBA