исключение «недостаточно памяти» в CRecordset при выборе столбца LONGTEXT в MySQL - PullRequest
0 голосов
/ 02 декабря 2008

Я использую CODBCRecordset (класс, найденный в CodeProject), чтобы найти одну запись в таблице с 39 столбцами. Если запись не найдена, то вызов CRecordset :: Open в порядке. Если запись соответствует условиям, я получаю исключение Out of Memory, когда вызывается CRecordset :: Open. Я выбираю все столбцы в запросе (если я изменяю запрос, чтобы выбрать только один из столбцов с тем же условием where, то не исключение).

Полагаю, это из-за некоторых ограничений в CRecordset, но я не могу найти ничего, что говорило бы мне о каких-либо ограничениях. В таблице только 39 столбцов.

Кто-нибудь сталкивался с этой проблемой? И если да, то есть ли у вас решение проблемы?

Это проект MFC, использующий Visual Studio 6.0, если он имеет какое-либо значение.

Вот запрос (отформатированный здесь, чтобы он отображался без полосы прокрутки):

    SELECT `id`, `member_id`, `member_id_last_four`, `card_number`, `first_name`,
           `mi`, `last_name`, `participant_title_id`, `category_id`, `gender`, 
           `date_of_birth`, `address_line_1`, `address_line_2`, `city`, `state`, 
           `zip`, `phone`, `work_phone`, `mobile_phone`, `fax`, `email`, 
           `emergency_name`, `emergency_phone`, `job_title`, `mail_code`, 
           `comments`, `contract_unit`, `contract_length`, `start_date`, 
           `end_date`, `head_of_household`, `parent_id`, `added_by`, `im_active`, 
           `ct_active`, `organization`, `allow_members`, `organization_category_id`,  
           `modified_date` 
   FROM `participants` 
   WHERE `member_id` = '27F7D0982978B470C5CF94B1B833CC93F997EE23'

Копирование и вставка в мой браузер запросов дает мне только один результат.

Дополнительная информация:

Закомментировал каждый столбец в операторе выбора, кроме идентификатора. Запустил запрос и без исключения.

Затем я систематически просматривал и раскомментировал каждый столбец, по одному, и перезапускал запрос между каждым комментарием.

Когда я раскомментирую столбец комментариев, я получаю сообщение об ошибке.

Это определяется следующим образом (с использованием MySQL): LONGTEXT

Ответы [ 3 ]

2 голосов
/ 02 декабря 2008

Можем ли мы предположить, что вы имеете в виду C ODBC Recordset :: Open (), да? Или, точнее, что-то вроде:

CDatabase db;
db.Open (NULL,FALSE,FALSE,"ODBC;",TRUE);
CODBCRecordSet rs (&db);
rs.Open ("select blah, blah, blah from ...");

РЕДАКТИРОВАТЬ после ответа:

Существует несколько известных ошибок с различными драйверами ODBC, которые, по-видимому, были вызваны получением недопустимых длин полей. Смотрите эти ссылки:

Этот конкретный случай, по-видимому, связан с тем, что CRecordset выделит буфер, достаточно большой для хранения поля. Поскольку столбец возвращает нулевую длину, он интерпретируется как максимальный 32-разрядный размер (~ 2 ГБ) вместо максимального 8-разрядного размера (255 байт). Излишне говорить, что он не может выделить достаточно памяти для поля.

Microsoft признала это проблемой, посмотрите на эти решения:

ИЗМЕНИТЬ после добавления вопроса:

Итак, учитывая, что ваше поле MySQL является LONGTEXT, кажется, что CRecordSet пытается выделить для него максимально возможный размер (2G). Вам действительно нужно 2 гигабайта для поля комментариев? Печатая со скоростью 80 об / мин, 6cpw потребовалось бы машинистке чуть более 7 лет, чтобы заполнить это поле, работая 24 часа в сутки без отдыха: -).

Может быть полезным посмотреть на все столбцы в вашей базе данных, чтобы увидеть, имеют ли они соответствующие типы данных. Я не говорю, что вы не можете иметь столбец 2G, просто вы должны быть уверены, что это необходимо, особенно в свете того факта, что текущие классы ODBC не будут работать с полем, которое большой.

0 голосов
/ 03 декабря 2008

Я второе предположение Пакса, что эта ошибка связана с попыткой выделить буфер достаточно большой, чтобы вместить максимально возможный LONGTEXT. Клиент не знает, насколько велики данные, пока не получит их.

LONGTEXT действительно намного больше, чем нужно в большинстве приложений. Попробуйте использовать MEDIUMTEXT (максимальный размер 16 МБ) или просто текст (максимальный размер 64 КБ).

Есть похожие проблемы в интерфейсах баз данных PHP. У PHP обычно есть предел размера памяти, и любая выборка LONGBLOB или LONGTEXT, вероятно, превысит этот предел.

0 голосов
/ 02 декабря 2008

Прочитайте ответ Пакс. Это дает вам отличное понимание того, почему возникает проблема.

Работа вокруг:

Эта ошибка произойдет, только если поле, определенное как (TEXT, LONGTEXT и т. Д.), Имеет значение NULL (и может быть пустым). Если в поле есть данные, он будет распределять данные только по размеру, а не по максимальному размеру (что приведет к ошибке).

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

  1. Дайте полю значение по умолчанию в базе данных. (т.е. '<blank>')
  2. Тогда при отображении значения; Вы передаете NULL / пусто, если найдете значение по умолчанию.
  3. Тогда при обновлении значения; вы передаете значение по умолчанию, если найдете NULL / пусто.
...