PHP sqlsrv_fetch_array перебирает только половину результатов

При переборе набора результатов (60 строк) PHP перебирает только несколько результатов. Если я не сортирую результаты, он возвращает четыре. Если я сортирую результаты по их идентификатору, он возвращает 31 результат. Я считаю, что это может иметь какое-то отношение к размеру данных в каждой строке, но я не уверен. Представление, из которого я выбираю, имеет 50 столбцов, примерно четверть из которых представляет собой HTML-код, и я полагаю, что они имеют тип данных varchar (max). Я использую следующие спецификации и код.
Microsoft SQL SERVER 2008
PHP 7.2
ODBC 17
Время выполнения PHP составляет 900 секунд
Ограничение памяти PHP составляет 4096 МБ.

$connection_info = array();
$connection_info["Database"] = "database";
$connection_info["UID"] = "username";
$connection_info["PWD"] = "password"
$connection = sqlsrv_connect( "server", $connection_info );
result = sqlsrv_query( $connection, "SELECT * FROM server.[database].[dbo].[table]", array(), array( "Scrollable" => SQLSRV_CURSOR_KEYSET ) );

while( $row = sqlsrv_fetch_array( $result, SQLSRV_FETCH_ASSOC ) ) {
    echo $row["id"] . " " . var_dump( sqlsrv_errors() ) . "<br>";
    }
echo var_dump( sqlsrv_errors() );

Последняя проверка sqlsrv_errors() возвращает ошибку:

array(1) { [0]=> array(6) { [0]=> string(5) 01004 [SQLSTATE]=> string(5) 01004 [1]=> int(0) [code]=> int (0) [2]=> строка (71) [Microsoft] [Драйвер ODBC 17 для SQL Server] Строковые данные, усечение справа [сообщение] => строка (71) [Microsoft] [Драйвер ODBC 17 для SQL Server] Строковые данные , усечение справа } }


person xevidos    schedule 05.09.2018    source источник
comment
Выдает ли while (sqlsrv_fetch($result)) {echo sqlsrv_get_field($result, 0 ).\n;} ошибку?   -  person Zhorov    schedule 05.09.2018
comment
Нет, это не так, это перебирает первое значение всех 63 результатов. Однако я попытался изменить 0 на 9 (один из столбцов, в котором много данных), и я получил идентификатор ресурса #, а затем номер идентификатора. sqlsrv_errors() возвращает ноль.   -  person xevidos    schedule 06.09.2018
comment
Хорошо, тогда вы можете правильно получить все данные строки с помощью sqlsrv_get_field()?   -  person Zhorov    schedule 06.09.2018
comment
К сожалению, это невозможно. Предполагается, что функция, в которой используется код, собирает данные из всех таблиц, перечисленных в массиве. Не все таблицы будут иметь одинаковое количество результатов или одинаковое количество столбцов.   -  person xevidos    schedule 06.09.2018
comment
Кто-нибудь когда-нибудь находил решение этого?   -  person onedeadgod    schedule 22.04.2019
comment
К сожалению нет. В итоге мы выбрали нужные нам данные из другой базы данных. Из-за того, что я никогда не находил решения, единственное, что я могу порекомендовать, это либо посмотреть, размещены ли данные в более чем одной базе данных, либо попытаться создать представление или SP для выбора данных.   -  person xevidos    schedule 24.04.2019
comment
Вы пробовали $connection_info['CharacterSet'] = 'UTF-8' (по умолчанию SQLSRV_ENC_CHAR) varchar против nvarchar и utf-8 против проблемы с кодировкой win1252   -  person GDmac    schedule 12.01.2021


Ответы (1)


У меня была аналогичная проблема.

Я обнаружил, что цикл останавливается, казалось бы, случайным образом. Вот как я исправил свою проблему. Когда цикл достигает точки, когда сервер выдает ошибку (что можно отобразить с помощью «sqlsrv_errors»)

while( $row = sqlsrv_fetch_array( $result, SQLSRV_FETCH_ASSOC ) ) {  
echo $row["id"] . " " . var_dump( sqlsrv_errors() ) . "<br>"; 
}

Вот как я избежал проблемы:

$params = array();
$options = array("Scrollable" => SQLSRV_CURSOR_KEYSET);
$result = sqlsrv_query($conn, $query, $params, $options);
for ($i = 0; $i < sqlsrv_num_rows($result); $i++) {
    $obj = sqlsrv_fetch_array($newq, SQLSRV_FETCH_NUMERIC, SQLSRV_SCROLL_ABSOLUTE, $i);
    echo $row[0]; 
}

Я думаю, что проблема возникает из-за того, что он не знает, как справиться с ошибкой, с которой он представлен, и по этой причине выходит из цикла.

Это документация, описывающая проблему

person Luke Price    schedule 10.01.2020
comment
Обратите внимание, что строка ошибки (которая возвращает false вместо null, обе из которых завершают исходный цикл) все равно будет потеряна, она просто не остановит цикл. - person Ben Jackson; 18.05.2021