資料指標類型 (SQLSRV 驅動程式)

下載 PHP 驅動程式

SQLSRV 驅動程式可讓您根據資料指標類型,建立能夠以任何順序存取資料列的結果集。 此主題將討論用戶端 (緩衝) 與伺服器端 (未緩衝) 的資料指標。

資料指標類型

當您搭配 sqlsrv_querysqlsrv_prepare 建立結果集時,您可以指定資料指標的類型。 根據預設,會使用順向資料指標,其可讓您從結果集的第一個資料列開始,一次移動一個資料列,直到您抵達結果集的結尾為止。

您可以搭配可捲動的資料指標建立結果集,其可讓您以任何順序存取結果集中的任何資料列。 下表列出可傳遞至 sqlsrv_query 或 sqlsrv_prepare 中 Scrollable 選項的值。

選項 描述
SQLSRV_CURSOR_FORWARD 讓您從結果集的第一個資料列開始,一次移動一個資料列,直到您抵達結果集的結尾為止。

此為預設的資料指標類型。

sqlsrv_num_rows 會針對搭配此資料指標類型所建立的結果集傳回錯誤。

forward 是 SQLSRV_CURSOR_FORWARD 的縮寫格式。
SQLSRV_CURSOR_STATIC 讓您以任何順序存取資料列,但將不會反映資料庫中的變更。

static 是 SQLSRV_CURSOR_STATIC 的縮寫格式。
SQLSRV_CURSOR_DYNAMIC 讓您以任何順序存取資料列,且會反映資料庫中的變更。

sqlsrv_num_rows 會針對搭配此資料指標類型所建立的結果集傳回錯誤。

dynamic 是 SQLSRV_CURSOR_DYNAMIC 的縮寫格式。
SQLSRV_CURSOR_KEYSET 讓您以任何順序存取資料列。 不過,如果資料列已從資料表中刪除,則索引鍵集資料指標不會更新資料列計數 (已刪除的資料列傳回時不會有值)。

keyset 是 SQLSRV_CURSOR_KEYSET 的縮寫格式。
SQLSRV_CURSOR_CLIENT_BUFFERED 讓您以任何順序存取資料列。 建立用戶端資料指標查詢。

buffered 是 SQLSRV_CURSOR_CLIENT_BUFFERED 的縮寫格式。

如果查詢會產生多個結果集,Scrollable 選項便會套用到所有結果集。

選取結果集中的資料列

在您建立結果集之後,您可以使用 sqlsrv_fetchsqlsrv_fetch_arraysqlsrv_fetch_object 來指定資料列。

下表描述可在 row 參數中指定的值。

參數 描述
SQLSRV_SCROLL_NEXT 指定下一個資料列。 此為您不針對可捲動的結果集指定 row 參數,這便會是預設值。
SQLSRV_SCROLL_PRIOR 指定目前資料列之前的資料列。
SQLSRV_SCROLL_FIRST 指定結果集中的第一個資料列。
SQLSRV_SCROLL_LAST 指定結果集中的最後一個資料列。
SQLSRV_SCROLL_ABSOLUTE 指定搭配 offset 參數指定的資料列。
SQLSRV_SCROLL_RELATIVE 指定從目前資料列算起搭配 offset 參數指定的資料列。

伺服器端資料指標和 SQLSRV 驅動程式

下列範例示範各種資料指標的效果。 在範例的行 33 上,您會看見指定不同資料指標的三個查詢陳述式中的第一個。 兩個查詢陳述式已加上註解。 每當您執行程式時,請使用不同的資料指標類型來在行 47 上查看資料庫更新的效果。

<?php  
$server = "server_name";  
$conn = sqlsrv_connect( $server, array( 'Database' => 'test' ));  
if ( $conn === false ) {  
   die( print_r( sqlsrv_errors(), true ));  
}  
  
$stmt = sqlsrv_query( $conn, "DROP TABLE dbo.ScrollTest" );  
if ( $stmt !== false ) {   
   sqlsrv_free_stmt( $stmt );   
}  
  
$stmt = sqlsrv_query( $conn, "CREATE TABLE ScrollTest (id int, value char(10))" );  
if ( $stmt === false ) {  
   die( print_r( sqlsrv_errors(), true ));  
}  
  
$stmt = sqlsrv_query( $conn, "INSERT INTO ScrollTest (id, value) VALUES(?,?)", array( 1, "Row 1" ));  
if ( $stmt === false ) {  
   die( print_r( sqlsrv_errors(), true ));  
}  
  
$stmt = sqlsrv_query( $conn, "INSERT INTO ScrollTest (id, value) VALUES(?,?)", array( 2, "Row 2" ));  
if ( $stmt === false ) {  
   die( print_r( sqlsrv_errors(), true ));  
}  
  
$stmt = sqlsrv_query( $conn, "INSERT INTO ScrollTest (id, value) VALUES(?,?)", array( 3, "Row 3" ));  
if ( $stmt === false ) {  
   die( print_r( sqlsrv_errors(), true ));  
}  
  
$stmt = sqlsrv_query( $conn, "SELECT * FROM ScrollTest", array(), array( "Scrollable" => 'keyset' ));  
// $stmt = sqlsrv_query( $conn, "SELECT * FROM ScrollTest", array(), array( "Scrollable" => 'dynamic' ));  
// $stmt = sqlsrv_query( $conn, "SELECT * FROM ScrollTest", array(), array( "Scrollable" => 'static' ));  
  
$rows = sqlsrv_has_rows( $stmt );  
if ( $rows != true ) {  
   die( "Should have rows" );  
}  
  
$result = sqlsrv_fetch( $stmt, SQLSRV_SCROLL_LAST );  
$field1 = sqlsrv_get_field( $stmt, 0 );  
$field2 = sqlsrv_get_field( $stmt, 1 );  
echo "\n$field1 $field2\n";  
  
$stmt2 = sqlsrv_query( $conn, "delete from ScrollTest where id = 3" );  
// or  
// $stmt2 = sqlsrv_query( $conn, "UPDATE ScrollTest SET id = 4 WHERE id = 3" );  
if ( $stmt2 !== false ) {   
   sqlsrv_free_stmt( $stmt2 );   
}  
  
$result = sqlsrv_fetch( $stmt, SQLSRV_SCROLL_LAST );  
$field1 = sqlsrv_get_field( $stmt, 0 );  
$field2 = sqlsrv_get_field( $stmt, 1 );  
echo "\n$field1 $field2\n";  
  
sqlsrv_free_stmt( $stmt );  
sqlsrv_close( $conn );  
?>  

用戶端資料指標和 SQLSRV 驅動程式

適用於 Microsoft Drivers for PHP for SQL Server 3.0 版中,已新增用戶端資料指標,讓您能夠在記憶體中快取整個結果集。 使用用戶端資料指標時,可在執行查詢之後使用資料列計數。

用戶端資料指標應該用於小型到中型的結果集。 請針對大型結果集使用伺服器端資料指標。

如果緩衝區因為不夠大而無法保存整個結果集,查詢將會傳回 false。 您可以將緩衝區大小上限提高到 PHP 記憶體限制。

透過使用 SQLSRV 驅動程式,您可以使用 sqlsrv_configure 的 ClientBufferMaxKBSize 設定來設定保存結果集的緩衝區大小。 sqlsrv_get_config 會傳回 ClientBufferMaxKBSize 的值。 您也可以在 php.ini 檔案中使用 sqlsrv.ClientBufferMaxKBSize 來設定緩衝區大小上限 (例如 sqlsrv.ClientBufferMaxKBSize = 1024)。

下列範例顯示︰

  • 資料列計數一律可搭配用戶端資料指標使用。

  • 用戶端資料指標和批次陳述式的使用。

<?php  
$serverName = "(local)";  
$connectionInfo = array("Database"=>"AdventureWorks");  
$conn = sqlsrv_connect( $serverName, $connectionInfo);  
  
if ( $conn === false ) {  
   echo "Could not connect.\n";  
   die( print_r( sqlsrv_errors(), true));  
}  
  
$tsql = "select * from HumanResources.Department";  
  
// Execute the query with client-side cursor.  
$stmt = sqlsrv_query($conn, $tsql, array(), array("Scrollable"=>"buffered"));  
if (! $stmt) {  
   echo "Error in statement execution.\n";  
   die( print_r( sqlsrv_errors(), true));  
}  
  
// row count is always available with a client-side cursor  
$row_count = sqlsrv_num_rows( $stmt );  
echo "\nRow count = $row_count\n";  
  
// Move to a specific row in the result set.  
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);  
$EmployeeID = sqlsrv_get_field( $stmt, 0);  
echo "Employee ID = $EmployeeID \n";  
  
// Client-side cursor and batch statements  
$tsql = "select top 2 * from HumanResources.Employee;Select top 3 * from HumanResources.EmployeeAddress";  
  
$stmt = sqlsrv_query($conn, $tsql, array(), array("Scrollable"=>"buffered"));  
if (! $stmt) {  
   echo "Error in statement execution.\n";  
   die( print_r( sqlsrv_errors(), true));  
}  
  
$row_count = sqlsrv_num_rows( $stmt );  
echo "\nRow count for first result set = $row_count\n";  
  
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);  
$EmployeeID = sqlsrv_get_field( $stmt, 0);  
echo "Employee ID = $EmployeeID \n";  
  
sqlsrv_next_result($stmt);  
  
$row_count = sqlsrv_num_rows( $stmt );  
echo "\nRow count for second result set = $row_count\n";  
  
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_LAST);  
$EmployeeID = sqlsrv_get_field( $stmt, 0);  
echo "Employee ID = $EmployeeID \n";  
?>  

下列範例顯示使用 sqlsrv_prepare 和不同用戶端緩衝區大小的用戶端資料指標。

<?php  
$serverName = "(local)";  
$connectionInfo = array( "Database"=>"AdventureWorks");  
$conn = sqlsrv_connect( $serverName, $connectionInfo);  
  
if ( $conn === false ) {  
   echo "Could not connect.\n";  
   die( print_r( sqlsrv_errors(), true));  
}  
  
$tsql = "select * from HumanResources.Employee";  
$stmt = sqlsrv_prepare( $conn, $tsql, array(), array("Scrollable" => SQLSRV_CURSOR_CLIENT_BUFFERED, "ClientBufferMaxKBSize" => 51200));
  
if (! $stmt ) {  
   echo "Statement could not be prepared.\n";  
   die( print_r( sqlsrv_errors(), true));  
}  
  
sqlsrv_execute( $stmt);  
  
$row_count = sqlsrv_num_rows( $stmt );  
if ($row_count)  
   echo "\nRow count = $row_count\n";  
  
$row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);  
if ($row ) {  
   $EmployeeID = sqlsrv_get_field( $stmt, 0);  
   echo "Employee ID = $EmployeeID \n";  
}  
?>  

另請參閱

指定資料指標類型及選取資料列