当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2023-07-12 18:14:22 浏览: 评论:0 

在 PHP 中使用 SQLSRV 查询时,如果查询结果集较大,可以考虑使用游标来提高查询效率。使用游标可以将查询结果集分成多个小部分进行处理,减轻服务器的负担,提高查询性能。

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

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

游标类型

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

Option Description

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行上的数据库更新效果。

  1. <?php   
  2. $server = "server_name";   
  3. $conn = sqlsrv_connect( $serverarray'Database' => 'test' ));   
  4. if ( $conn === false ) {   
  5.    die( print_r( sqlsrv_errors(), true ));   
  6. }   
  7. $stmt = sqlsrv_query( $conn"DROP TABLE dbo.ScrollTest" );   
  8. if ( $stmt !== false ) {    
  9.    sqlsrv_free_stmt( $stmt );    
  10. }   
  11. $stmt = sqlsrv_query( $conn"CREATE TABLE ScrollTest (id int, value char(10))" );   
  12. if ( $stmt === false ) {   
  13.    die( print_r( sqlsrv_errors(), true ));   
  14. }   
  15. $stmt = sqlsrv_query( $conn"INSERT INTO ScrollTest (id, value) VALUES(?,?)"array( 1, "Row 1" ));   
  16. if ( $stmt === false ) {   
  17.    die( print_r( sqlsrv_errors(), true ));   
  18. }   
  19. $stmt = sqlsrv_query( $conn"INSERT INTO ScrollTest (id, value) VALUES(?,?)"array( 2, "Row 2" ));   
  20. if ( $stmt === false ) {   
  21.    die( print_r( sqlsrv_errors(), true ));   
  22. }   
  23. $stmt = sqlsrv_query( $conn"INSERT INTO ScrollTest (id, value) VALUES(?,?)"array( 3, "Row 3" ));   
  24. if ( $stmt === false ) {   
  25.    die( print_r( sqlsrv_errors(), true ));   
  26. }   
  27. $stmt = sqlsrv_query( $conn"SELECT * FROM ScrollTest"array(), array"Scrollable" => 'keyset' ));   
  28. // $stmt = sqlsrv_query( $conn, "SELECT * FROM ScrollTest", array(), array( "Scrollable" => 'dynamic' ));   
  29. // $stmt = sqlsrv_query( $conn, "SELECT * FROM ScrollTest", array(), array( "Scrollable" => 'static' ));   
  30. $rows = sqlsrv_has_rows( $stmt );   
  31. if ( $rows != true ) {   
  32.    die"Should have rows" );   
  33. }   
  34. $result = sqlsrv_fetch( $stmt, SQLSRV_SCROLL_LAST );   
  35. $field1 = sqlsrv_get_field( $stmt, 0 );   
  36. $field2 = sqlsrv_get_field( $stmt, 1 );   
  37. echo "\n$field1 $field2\n";   
  38. $stmt2 = sqlsrv_query( $conn"delete from ScrollTest where id = 3" );   
  39. // or   
  40. // $stmt2 = sqlsrv_query( $conn, "UPDATE ScrollTest SET id = 4 WHERE id = 3" );   
  41. if ( $stmt2 !== false ) {    
  42.    sqlsrv_free_stmt( $stmt2 );    
  43. }   
  44. $result = sqlsrv_fetch( $stmt, SQLSRV_SCROLL_LAST );   
  45. $field1 = sqlsrv_get_field( $stmt, 0 );   
  46. $field2 = sqlsrv_get_field( $stmt, 1 );   
  47. echo "\n$field1 $field2\n";   
  48. sqlsrv_free_stmt( $stmt );   
  49. sqlsrv_close( $conn );   
  50. ?> 

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、使用客户端游标和批处理语句。

  1. <?php   
  2. $serverName = "(local)";   
  3. $connectionInfo = array("Database"=>"AdventureWorks");   
  4. $conn = sqlsrv_connect( $serverName$connectionInfo);   
  5. if ( $conn === false ) {   
  6.    echo "Could not connect.\n";   
  7.    die( print_r( sqlsrv_errors(), true));   
  8. }   
  9. $tsql = "select * from HumanResources.Department";   
  10. // Execute the query with client-side cursor.   
  11. $stmt = sqlsrv_query($conn$tsqlarray(), array("Scrollable"=>"buffered"));   
  12. if (! $stmt) {   
  13.    echo "Error in statement execution.\n";   
  14.    die( print_r( sqlsrv_errors(), true));   
  15. }   
  16. // row count is always available with a client-side cursor   
  17. $row_count = sqlsrv_num_rows( $stmt );   
  18. echo "\nRow count = $row_count\n";   
  19. // Move to a specific row in the result set.   
  20. $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);   
  21. $EmployeeID = sqlsrv_get_field( $stmt, 0);   
  22. echo "Employee ID = $EmployeeID \n";   
  23. // Client-side cursor and batch statements   
  24. $tsql = "select top 2 * from HumanResources.Employee;Select top 3 * from HumanResources.EmployeeAddress";   
  25. $stmt = sqlsrv_query($conn$tsqlarray(), array("Scrollable"=>"buffered"));   
  26. if (! $stmt) {   
  27.    echo "Error in statement execution.\n";   
  28.    die( print_r( sqlsrv_errors(), true));   
  29. }   
  30. $row_count = sqlsrv_num_rows( $stmt );   
  31. echo "\nRow count for first result set = $row_count\n";   
  32. $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);   
  33. $EmployeeID = sqlsrv_get_field( $stmt, 0);   
  34. echo "Employee ID = $EmployeeID \n";   
  35. sqlsrv_next_result($stmt);   
  36. $row_count = sqlsrv_num_rows( $stmt );   
  37. echo "\nRow count for second result set = $row_count\n";   
  38. $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_LAST);   
  39. $EmployeeID = sqlsrv_get_field( $stmt, 0);   
  40. echo "Employee ID = $EmployeeID \n";   
  41. ?> 

以下示例显示了使用sqlsrv_prepare(sqlsrv_prepare)并配置了不同的客户端缓冲区大小。

  1. <?php   
  2. $serverName = "(local)";   
  3. $connectionInfo = array"Database"=>"AdventureWorks");   
  4. $conn = sqlsrv_connect( $serverName$connectionInfo);   
  5. if ( $conn === false ) {   
  6.    echo "Could not connect.\n";   
  7.    die( print_r( sqlsrv_errors(), true));   
  8. }   
  9. $tsql = "select * from HumanResources.Employee";   
  10. $stmt = sqlsrv_prepare( $conn$tsqlarray(), array("Scrollable" => SQLSRV_CURSOR_CLIENT_BUFFERED, "ClientBufferMaxKBSize" => 51200)); 
  11. if (! $stmt ) {   
  12.    echo "Statement could not be prepared.\n";   
  13.    die( print_r( sqlsrv_errors(), true));   
  14. }   
  15. sqlsrv_execute( $stmt);   
  16. $row_count = sqlsrv_num_rows( $stmt );   
  17. if ($row_count)   
  18.    echo "\nRow count = $row_count\n";   
  19. $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST);   
  20. if ($row ) {   
  21.    $EmployeeID = sqlsrv_get_field( $stmt, 0);   
  22.    echo "Employee ID = $EmployeeID \n";   
  23. }   
  24. ?>

Tags: SQLSRV PHP查询方法

分享到: