& # 8220; sin memoria & # 8221; excepción en CRecordset al seleccionar una columna LONGTEXT de MySQL

StackOverflow https://stackoverflow.com/questions/333169

Pregunta

Estoy usando CODBCRecordset (una clase que se encuentra en CodeProject) para encontrar un único registro en una tabla con 39 columnas. Si no se encuentra ningún registro, la llamada a CRecordset :: Open está bien. Si un registro coincide con las condiciones, obtengo una excepción de Memoria insuficiente cuando se llama a CRecordset :: Open. Estoy seleccionando todas las columnas en la consulta (si cambio la consulta para seleccionar solo una de las columnas con la misma cláusula where, entonces no hay excepción).

Supongo que esto se debe a alguna limitación en CRecordset, pero no puedo encontrar nada que me diga ninguna limitación. La tabla solo tiene 39 columnas.

¿Alguien ha tenido este problema? Y si es así, ¿tiene una solución alternativa?

Este es un proyecto MFC que usa Visual Studio 6.0 si hace alguna diferencia.

Aquí está la consulta (formateada aquí para que aparezca sin una barra de desplazamiento):

    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'

Copiar y pegar en mi navegador de consultas me da un solo resultado.

Más información:

Comentó cada columna en la instrucción select, excepto para id. Ejecuté la consulta y sin excepción.

Luego revisé sistemáticamente y descomenté cada columna, una a la vez, y volví a ejecutar la consulta entre cada comentario.

Cuando descomento la columna de comentarios, aparece el error.

Esto se define como lo siguiente (Usando MySQL): LONGTEXT

¿Fue útil?

Solución 3

Lee la respuesta de Pax. Le brinda una gran comprensión sobre por qué ocurre el problema.

Solución:

Este error solo ocurrirá si el campo definido como (TEXT, LONGTEXT, etc.) es NULL (y puede que esté vacío). Si hay datos en el campo, solo asignará el tamaño de los datos en el campo y no el tamaño máximo (lo que provocará el error).

Entonces, si hay un caso en el que absolutamente debe tener estos campos grandes. Aquí hay una posible solución:

  1. Otorgue al campo un valor predeterminado en la base de datos. (es decir, '< blank >' )
  2. Luego, cuando se muestra el valor; pasa NULL / empty si encuentra el valor predeterminado.
  3. Luego, al actualizar el valor; pasa el valor predeterminado si encuentra NULL / empty.

Otros consejos

¿Podemos suponer que quiere decir que está llamando a C ODBC Recordset :: Open (), sí? O más precisamente, algo como:

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

EDITAR después de la respuesta:

Hay algunos errores conocidos con varios controladores ODBC que parecen ser causados ??por la recuperación de longitudes de campo no válidas. Ver estos enlaces:

Este en particular parece haber sido porque CRecordset asignará un búfer lo suficientemente grande como para contener el campo. A medida que la columna devuelve una longitud de cero, se interpreta como el tamaño máximo de 32 bits (~ 2G) en lugar del tamaño máximo de 8 bits (255 bytes). No hace falta decir que no puede asignar suficiente memoria para el campo.

Microsoft ha reconocido esto como un problema, eche un vistazo a estas soluciones:

EDITAR después de los apéndices de preguntas:

Entonces, dado que su campo MySQL es un LONGTEXT, parece que CRecordSet está tratando de asignarle el tamaño máximo posible (2G). ¿Realmente necesitas 2 conciertos para un campo de comentarios? Escribiendo a 80 palabras por minuto, 6cpw tomaría un mecanógrafo un poco más de 7 años para llenar ese campo, trabajando 24 h / día sin descanso :-).

Puede ser un ejercicio útil echar un vistazo a todas las columnas de su base de datos para ver si tienen los tipos de datos apropiados. No estoy diciendo que no se puede tener una columna 2G, solo que debe estar seguro de que es necesario, especialmente a la luz del hecho de que las clases ODBC actuales no funcionarán con un campo así de grande.

Secundo la sugerencia de Pax de que este error se debe a tratar de asignar un búfer lo suficientemente grande como para contener el LONGTEXT más grande posible. El cliente no sabe qué tan grandes son los datos hasta que los ha obtenido.

LONGTEXT es mucho más grande de lo que necesitarías en la mayoría de las aplicaciones. Considere usar MEDIUMTEXT (tamaño máximo 16 MB) o simplemente TEXTO (tamaño máximo 64 KB) en su lugar.

Hay problemas similares en las interfaces de bases de datos PHP. Un PHP normalmente tiene un límite de tamaño de memoria y es probable que cualquier búsqueda de un LONGBLOB o LONGTEXT exceda ese límite.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top