sqlsrv array doesn't return all rows

When I try to view the result set

      $row = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC );
      print_r($row);`

Since you listed this separately, I hope you're not doing this (showing all code):

$col = 'abcd';
$stmt = "SELECT id, [description] FROM dbo.tbl WHERE col = ?";
$params = array( $col );
$options =  array( "Scrollable" => SQLSRV_CURSOR_KEYSET );

$query = sqlsrv_query( $conn, $stmt, $params, $options );
if( $query === false ) {
    print( print_r( sqlsrv_errors() ) );
}

while( $row = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC )) {
    ...
    $row = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC );
    print_r($row);
}

Because then it's obvious you're consuming sqlsrv_fetch_array twice per loop iteration, once for the condition check and once inside the loop.

Remove all fluff from the while loop and have just this - and absolutely nothing else, not even the ... or comments.

while( $row = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC )) {
    print_r($row);
}

sqlsrv_fetch_array: Returns the next available row of data as an associative array, a numeric array, or both (the default).

Emphasis by me.

Return Values: Returns an array on success, NULL if there are no more rows to return, and FALSE if an error occurs.

You'll need to do a while loop to fetch all records, like this:

while ($row = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC )) {
    //process $row
}