Запрос ODBC на MS SQL Server, возвращающий первые 255 символов только в PHP PDO (FreeTDS)

В настоящее время я пытаюсь извлечь некоторые данные из представления базы данных SQL Server, к которым у нас есть ограниченный доступ с нашего веб-сервера Linux.

Нам не нужно редактировать данные, просто отобразите их на веб-странице.

Все выглядит нормально, пока мы не попытаемся вывести и получим только первые 255 символов текстового поля.

Кто-нибудь знает, является ли это проблемой при использовании FreeTDS через PHP::PDO или все должно работать нормально? Я видел других людей, у которых были подобные проблемы, но, похоже, не так много ответов.

Я использую это как строку подключения для базы данных MS SQL:

$dbConn = new PDO("odbc:Driver=FreeTDS;DSN=OURDSN;UID=WWWUser;PWD=ourpassword");

person Del    schedule 09.03.2010    source источник


Ответы (4)


Согласно Руководству пользователя FreeTDS проблема заключается в том, что FreeTDS может обрабатывать только varchar до 255 символов при обращении к SQL Server "из-за ограничений, присущих определению протокола". Все, что больше этого, должно иметь тип данных text.

Вы можете решить эту проблему, либо соответствующим образом изменив схему, либо преобразовав тип данных во время запроса, например:

SELECT CAST(mycol as TEXT) FROM mytable
person D'Arcy Rittich    schedule 09.03.2010
comment
Аналогичная проблема существует при использовании MS ODBC в Windows Server 2016 на SQL Server 2016, хотя она возвращает ваше значение с нулевыми байтами, вставленными через каждые 256 байтов, и этот обходной путь устраняет проблему. Другой вариант — использовать str_replace("\0", '', $string) для удаления нулевых байтов. - person Aaron Mason; 06.11.2017

Вы можете увеличить размер текстовых полей в файле /etc/odbc.ini, используемом FreeTDS.

[name_of_connection]
TextSize = 2097152

Вы также можете попробовать использовать подпрограммы PHP низкого уровня odbc, чтобы убедиться, что вы можете получить этот уровень поиска данных, а затем вернуться к использованию PDO.

person Tony Miller    schedule 09.03.2010
comment
Мы пробовали это, поскольку казалось, что это единственное, что можно было попробовать, но, похоже, это не дало никакого эффекта. Хотя вполне возможно, что я что-то делаю не так. Нужно ли перезапускать какие-либо другие процессы после изменения файла odbc.ini? - person Del; 09.03.2010

FreeTDS по умолчанию использует протокол версии 4.2. Если вы используете протокол до 7.0, вы можете получить более 255 байтов varchar. Вы можете использовать хак «CAST», или вы можете ИЗМЕНИТЬ COLUMN col varchar(max).

varchar(max) — это совершенно другой тип столбца, чем varchar (DATA_TYPE 2005 по сравнению с 12), и он будет передаваться через freetds 4.2 без усечения.

Почему бы не обновиться до версии 7? Потому что UTF-8 нельзя хранить в varchar с более новыми протоколами. SQL Server будет передавать ВСЮ информацию о протоколе в UCS-2 (например, UTF-16) и преобразовывать ваши данные в таблицы или столбцы перед сохранением. Но для этого требуется, чтобы вы префиксировали данные UTF8 с помощью N. INSERT в значения tbl (txt) (N'hello world')

Почему не КАСТ? CAST AS TEXT не совместим с MySQL (необходимо использовать CAST AS CHAR).

Оставаясь на протоколе 4.2 и определяя ваши varchars как varchar(max), вы можете написать наиболее совместимый SQL.

person chugadie    schedule 13.06.2014
comment
Спасибо за это, но я решил это четыре года назад и больше не имею ничего общего с этой настройкой. - person Del; 16.06.2014
comment
Да, но я просто унаследовал эту проблему и хотел добавить в копилку знаний. На всякий случай есть еще люди, унаследовавшие системы, построенные на технологиях 1998 года. - person chugadie; 18.06.2014

Еще один факт по этому вопросу. По состоянию на 2015 год при возврате значения типа XML первые 256 символов возвращаются корректно. Однако большая часть остального XML будет возвращена как явно случайный мусор с редкими четкими фрагментами текста. На самом деле, если бы мне пришлось угадывать, запрос возвращает случайный блок памяти для всех символов после 256.

В моем конкретном случае я генерировал XML (используя несколько вложенных запросов FOR XML) для отправки на веб-сайт для отображения. В этом случае решение, которое я нашел, состояло в том, чтобы использовать хак CAST, переводя данные в varchar(max).

Так что помните: если вы видите блок из 256 чистых символов, за которым следует случайный мусор в результатах вашего запроса, это, вероятно, значение XML, возвращаемое как тип XML, а не тип varchar(max).

ПРЕДОСТЕРЕЖЕНИЕ: Это может применяться только в том случае, если XML создается динамически.

person Laughing Vergil    schedule 17.11.2015