使用游标进行PHP SQLSRV查询的方法与注意事项

 更新时间:2023年05月08日 09:52:19   作者:cncco  
在 PHP 中使用 SQLSRV 查询时,如果查询结果集较大,可以考虑使用游标来提高查询效率。使用游标可以将查询结果集分成多个小部分进行处理,减轻服务器的负担,提高查询性能

SQLSRV驱动程序允许您创建一个结果集,其中包含可以根据游标类型以任何顺序访问的行。本主题将讨论客户端(缓冲)和服务器端(非缓冲)游标及其用法。

使用SQLSRV查询时,默认情况下,使用向前游标,它允许您从结果集的第一行开始一次移动一行,直到到达结果集的末尾。当然,有时这不是你所期待的,这就需要指定游标类型。

游标类型

您可以使用Scrollable来指定结果集的游标,以实现各种以顺序访问结果集中的任何行。下表列出了可以传递给Scrollable的选项。

OptionDescription
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_fetch、sqlsrv_fetch_array或sqlsrv_fetch_object来指定行了。

下表说明了可以对行进行的操作。

参数描述
SQLSRV_SCROLL_NEXT指定下一行。
SQLSRV_SCROLL_PRIOR指定当前行之前的行。
SQLSRV_SCROLL_FIRST指定结果集中的第一行。
SQLSRV_SCROLL_LAST指定结果集中的最后一行。
SQLSRV_SCROLL_ABSOLUTE指定指定的行抵消参数。
SQLSRV_SCROLL_RELATIVE指定指定的行抵消当前行中的参数。

SQLSRV Driver之服务端游标

以下示例显示了各种游标的效果。在示例的第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 Driver之客户端游标

客户端游标是Microsoft Drivers for PHP for SQL Server 3.0版中添加的一项功能,它允许您在内存中缓存整个结果集。使用客户端游标执行查询后,行计数可用。

客户端游标应该用于中小型结果集。对大型结果集使用服务器端游标。

如果缓冲区不够大,无法容纳整个结果集,则查询将返回false。您可以将缓冲区大小增加到PHP内存限制。

使用SQLSRV驱动程序,可以使用sqlsrv_configure来设置ClientBufferMaxKBSize以配置保存结果集的缓冲区的大小。

sqlsrv_get_config返回ClientBufferMaxKBSize的值。

您还可以在php.ini文件中使用sqlsrv.ClientBufferMaxKBSize来设置最大缓冲区大小(例如,sqlsrv.clientBufferMaxKBSign=1024)。

以下示例显示:

1、行计数始终可用于客户端游标。

2、使用客户端游标和批处理语句。

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

到此这篇关于使用游标进行PHP SQLSRV查询的方法与注意事项的文章就介绍到这了,更多相关PHP SQLSRV游标查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • php rename错误原因的查找方法

    php rename错误原因的查找方法

    在本篇文章里小编给大家整理的是一篇关于php rename错误原因的查找方法,有需要的朋友们可以跟着学习参考下。
    2021-07-07
  • PHP实现页面跳转的三种方式

    PHP实现页面跳转的三种方式

    在PHP中,实现页面跳转有多种方法,这些方法包括使用HTTP头信息、JavaScript以及Meta标签,本文给大家介绍了PHP实现页面跳转的三种方式,并通过代码讲解的非常详细,需要的朋友可以参考下
    2024-11-11
  • 基于php伪静态的实现方法解析

    基于php伪静态的实现方法解析

    这篇文章主要介绍了基于php伪静态的实现方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • php中session定期自动清理的方法

    php中session定期自动清理的方法

    这篇文章主要介绍了php中session定期自动清理的方法,如何设置php实现session定期自动清理,本文会给大家详细介绍,需要的朋友可以参考下
    2015-11-11
  • 实现了一个PHP5的getter/setter基类的代码

    实现了一个PHP5的getter/setter基类的代码

    实现了一个PHP5的getter/setter基类的代码...
    2007-02-02
  • 一文详解php中.env实现原理

    一文详解php中.env实现原理

    在PHP中,.env文件是一种常见的配置文件格式,用于存储应用程序的环境变量,本文将给大家大家详细的介绍一下php中.env实现原理,文中给出了简单的示例代码,需要的朋友可以参考下
    2024-01-01
  • php创建桌面快捷方式实现方法

    php创建桌面快捷方式实现方法

    这篇文章主要介绍了php创建桌面快捷方式实现方法,需要的朋友可以参考下
    2015-12-12
  • 在yii中新增一个用户验证的方法详解

    在yii中新增一个用户验证的方法详解

    本篇文章是对在yii中新增一个用户验证的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • thinkphp如何传递GET参数方法详解

    thinkphp如何传递GET参数方法详解

    这篇文章主要为大家介绍了thinkphp如何传递GET参数方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • PHPUnit测试私有属性和方法功能示例

    PHPUnit测试私有属性和方法功能示例

    这篇文章主要介绍了PHPUnit测试私有属性和方法功能,结合实例形式较为详细的分析了使用PHPUnit针对私有属性和方法进行测试的相关操作技巧与注意事项,需要的朋友可以参考下
    2018-06-06

最新评论