다음을 통해 공유


커서 유형(SQLSRV 드라이버)

PHP 드라이버 다운로드

SQLSRV 드라이버를 사용하면 커서 유형에 따라 어떤 순서로든지 액세스할 수 있는 행이 있는 결과 집합을 만들 수 있습니다. 이 항목에서는 클라이언트 쪽(버퍼링됨) 및 서버 쪽(버퍼링되지 않음) 커서에 대해 설명합니다.

커서 유형

커서 형식은 sqlsrv_query 또는 sqlsrv_prepare로 결과 집합을 만들 때 지정할 수 있습니다. 기본적으로 정방향 전용 커서가 사용되므로 결과 집합의 끝에 도달할 때까지 결과 집합의 첫 번째 행에서 시작하여 한 번에 한 행씩 이동할 수 있습니다.

스크롤 가능한 커서를 사용하여 결과 집합의 모든 행에 순서와 상관없이 액세스할 수 있는 결과 집합을 만들 수 있습니다. 다음 테이블에는 sqlsrv_query 또는 sqlsrv_prepare에서 스크롤 가능 옵션에 전달할 수 있는 값이 나열되어 있습니다.

옵션 설명
SQLSRV_CURSOR_FORWARD 결과 집합의 끝에 도달할 때까지 결과 집합의 첫 번째 행에서 시작하여 한 번에 한 행씩 이동할 수 있습니다.

이 형식이 기본 커서 형식입니다.

sqlsrv_num_rows는 이 커서 형식을 사용하여 만들어진 결과 집합에 대한 오류를 반환합니다.

forward는 SQLSRV_CURSOR_FORWARD의 약어 형식입니다.
SQLSRV_CURSOR_STATIC 순서에 관계없이 행에 액세스할 수 있지만, 데이터베이스에 변경 내용이 반영됩니다.

고정은 SQLSRV_CURSOR_STATIC의 약식 형식입니다.
SQLSRV_CURSOR_DYNAMIC 순서에 관계없이 행에 액세스할 수 있으며 데이터베이스에 변경 내용이 반영됩니다.

sqlsrv_num_rows는 이 커서 형식을 사용하여 만들어진 결과 집합에 대한 오류를 반환합니다.

동적은 SQLSRV_CURSOR_DYNAMIC의 약식 형식입니다.
SQLSRV_CURSOR_KEYSET 순서에 따라 행에 액세스할 수 있습니다. 그러나 테이블에서 행이 삭제되면 키 집합 커서가 행 수를 업데이트하지 않습니다(삭제된 행은 값 없이 반환됨).

키 집합은 SQLSRV_CURSOR_KEYSET의 약식 형식입니다.
SQLSRV_CURSOR_CLIENT_BUFFERED 순서에 따라 행에 액세스할 수 있습니다. 클라이언트 쪽 커서 쿼리를 만듭니다.

버퍼링됨은 SQLSRV_CURSOR_CLIENT_BUFFERED의 약식 형식입니다.

쿼리가 여러 결과 집합을 생성하는 경우 스크롤 가능 옵션이 모든 결과 집합에 적용됩니다.

결과 집합에서 행 선택

결과 집합을 만든 후 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 드라이버

다음 예시는 여러 커서의 효과를 보여줍니다. 예시의 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에 추가된 기능입니다. 행 수는 클라이언트 쪽 커서를 사용할 때 쿼리가 실행된 후에 사용할 수 있습니다.

클라이언트 쪽 커서는 중소 규모의 결과 집합에 사용해야 합니다. 큰 결과 집합에 서버 쪽 커서를 사용합니다.

버퍼가 전체 결과 집합을 담을 만큼 충분히 크지 않은 경우 쿼리는 거짓을 반환합니다. 버퍼 크기는 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";  
}  
?>  

참고 항목

커서 유형 지정 및 행 선택