Tipos de cursor (controlador SQLSRV)

Descargar controlador PHP

El controlador SQLSRV permite crear un conjunto de resultados con filas a las que se puede acceder en cualquier orden según el tipo de cursor. En este tema se explican los cursores del lado cliente (almacenados en búfer) y del lado servidor (no almacenados en búfer).

Tipos de cursor

Cuando se crea un conjunto de resultados con sqlsrv_query o con sqlsrv_prepare, se puede especificar el tipo de cursor. De forma predeterminada, se usa un cursor de solo avance, que permite desplazar una fila cada vez comenzando en la primera fila del conjunto de resultados hasta llegar al final.

Puede crear un conjunto de resultados con un cursor desplazable, que le permite tener acceso a cualquier fila del conjunto de resultados, en cualquier orden. En la tabla siguiente se muestran los valores que se pueden pasar a la opción Scrollable en sqlsrv_query o sqlsrv_prepare.

Opción Descripción
SQLSRV_CURSOR_FORWARD Permite desplazar una fila cada vez comenzando en la primera fila del conjunto de resultados hasta llegar al final.

Este es el tipo de cursor predeterminado.

sqlsrv_num_rows devuelve un error para los conjuntos de resultados creados con este tipo de cursor.

forward es la forma abreviada de SQLSRV_CURSOR_FORWARD.
SQLSRV_CURSOR_STATIC Permite acceder a las filas en cualquier orden, pero no reflejará los cambios en la base de datos.

static es la forma abreviada de SQLSRV_CURSOR_STATIC.
SQLSRV_CURSOR_DYNAMIC Permite acceder a las filas en cualquier orden y reflejará los cambios en la base de datos.

sqlsrv_num_rows devuelve un error para los conjuntos de resultados creados con este tipo de cursor.

dynamic es la forma abreviada de SQLSRV_CURSOR_DYNAMIC.
SQLSRV_CURSOR_KEYSET Permite acceder a las filas en cualquier orden. Pero los cursores de conjunto de claves no actualizan el recuento de filas si se elimina una fila de la tabla (las filas eliminadas se devuelven sin valores).

keyset es la forma abreviada de SQLSRV_CURSOR_KEYSET.
SQLSRV_CURSOR_CLIENT_BUFFERED Permite acceder a las filas en cualquier orden. Crea una consulta de cursor del lado cliente.

buffered es la forma abreviada de SQLSRV_CURSOR_CLIENT_BUFFERED.

Si una consulta genera varios conjuntos de resultados, la opción Scrollable se aplica a todos ellos.

Selección de filas en un conjunto de resultados

Después de crear un conjunto de resultados, puede usar sqlsrv_fetch, sqlsrv_fetch_array o sqlsrv_fetch_object para especificar una fila.

En la tabla siguiente se describen los valores que se pueden especificar en el parámetro row.

Parámetro Descripción
SQLSRV_SCROLL_NEXT Especifica la siguiente fila. Este es el valor predeterminado si no se especifica el parámetro row para un conjunto de resultados desplazable.
SQLSRV_SCROLL_PRIOR Especifica la fila delante de la fila actual.
SQLSRV_SCROLL_FIRST Especifica la primera fila del conjunto de resultados.
SQLSRV_SCROLL_LAST Especifica la última fila del conjunto de resultados.
SQLSRV_SCROLL_ABSOLUTE Indica la fila especificada con el parámetro offset.
SQLSRV_SCROLL_RELATIVE Indica la fila especificada con parámetro offset de la fila actual.

Cursores del lado servidor y el controlador SQLSRV

En el ejemplo siguiente se muestra el efecto de los distintos cursores. En la línea 33 del ejemplo, verá la primera de tres instrucciones de consulta que especifican cursores diferentes. Dos de las instrucciones de consulta están comentadas. Cada vez que ejecute el programa, use un tipo de cursor diferente para ver el efecto de la actualización de la base de datos en la línea 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 );  
?>  

Cursores del lado cliente y el controlador SQLSRV

Los cursores del lado cliente son una característica agregada a la versión 3.0 de Controladores de Microsoft para PHP para SQL Server que permite almacenar en caché un conjunto de resultados completo en memoria. El recuento de filas está disponible después de ejecutar la consulta cuando se usa un cursor del lado cliente.

Los cursores del lado cliente deben usarse para conjuntos de resultados de tamaño pequeño a mediano. Con conjuntos de resultados grandes se deben usar cursores del lado servidor.

Una consulta devolverá False si el búfer no es lo suficientemente grande como para contener todo el conjunto de resultados. Puede aumentar el tamaño del búfer hasta el límite de memoria PHP.

Con el controlador SQLSRV, puede configurar el tamaño del búfer que contiene el conjunto de resultados con el valor ClientBufferMaxKBSize de sqlsrv_configure. sqlsrv_get_config devuelve el valor de ClientBufferMaxKBSize. También puede establecer el tamaño máximo del búfer en el archivo php.ini con sqlsrv.ClientBufferMaxKBSize (por ejemplo, sqlsrv.ClientBufferMaxKBSize = 1024).

El ejemplo siguiente muestra:

  • El recuento de filas siempre está disponible con un cursor del lado cliente.

  • Uso de cursores del lado cliente e instrucciones por lotes.

<?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";  
?>  

En el ejemplo siguiente se muestra un cursor del lado cliente mediante sqlsrv_prepare y un tamaño de búfer de cliente diferente.

<?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";  
}  
?>  

Consulte también

Especificación de un tipo de cursor y selección de filas