0

我正在使用 CODBCRecordset(CodeProject 上的一个类)在具有 39 列的表中查找单个记录。如果没有找到记录,那么调用 CRecordset::Open 就可以了。如果记录与条件匹配,则在调用 CRecordset::Open 时会出现内存不足异常。我正在选择查询中的所有列(如果我将查询更改为仅选择具有相同 where 子句的列之一,那么也不例外)。

我认为这是因为 CRecordset 中的一些限制,但我找不到任何告诉我任何限制的信息。该表只有 39 列。

有没有人遇到过这个问题?如果是这样,您是否有解决方法/解决方案?

这是一个使用 Visual Studio 6.0 的 MFC 项目,如果它有什么不同的话。

这是查询(此处格式化,因此将在没有滚动条的情况下显示):

    选择`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`、  
           `修改日期`
   来自“参与者”
   WHERE `member_id` = '27F7D0982978B470C5CF94B1B833CC93F997EE23'

复制并粘贴到我的查询浏览器中只会给我一个结果。

更多信息:

注释掉 select 语句中除 id 之外的每一列。运行查询,没有例外。

然后我系统地检查并取消注释每一列,一次一个,并在每次取消注释之间重新运行查询。

当我取消注释评论列时,我得到了错误。

这被定义如下(使用 MySQL): LONGTEXT

4

3 回答 3

2

我们可以假设您的意思是您正在调用 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 位大小 (~2G) 而不是最大 8 位大小(255 字节)。不用说,它不能为字段分配足够的内存。

Microsoft 已承认这是一个问题,请查看以下解决方案:

问题附录后编辑:

因此,鉴于您的 MySQL 字段是 LONGTEXT,CRecordSet 似乎正在尝试为其分配最大可能大小(2G)。你真的需要 2 场演出来评论区吗?以 80 wpm 和 6cpw 的速度打字需要一个打字员 7 年多一点的时间来填补这个领域,每天 24 小时工作,没有休息:-)。

查看数据库中的所有列以查看它们是否具有适当的数据类型可能是一个有用的练习。我并不是说你不能有一个 2G 列,只是你应该确定它是必要的,特别是考虑到当前的 ODBC 类不适用于这么大的字段这一事实。

于 2008-12-02T06:20:30.317 回答
0

阅读 Pax 的回复。它使您对问题发生的原因有了很好的理解。

解决方法:

仅当定义为(TEXT、LONGTEXT 等)的字段为 NULL(并且可能为空)时,才会发生此错误。如果字段中有数据,那么它将仅分配字段中数据的大小而不是最大大小(从而导致错误)。

因此,如果在某些情况下您绝对必须拥有这些大字段。这是一个潜在的解决方案:

  1. 在数据库中为该字段指定一个默认值。(即。'<blank>'
  2. 然后在显示值的时候;如果找到默认值,则传递 NULL/empty。
  3. 然后在更新值时;如果发现 NULL/空,则传递默认值。
于 2008-12-02T07:03:34.237 回答
0

我同意 Pax 的建议,即此错误是由于尝试分配足够大的缓冲区以容纳可能的最大 LONGTEXT。客户端在获取数据之前不知道数据有多大。

LONGTEXT 确实比您在大多数应用程序中所需要的要大得多。考虑使用 MEDIUMTEXT(最大大小 16MB)或仅使用 TEXT(最大大小 64KB)。

PHP数据库接口也有类似的问题。PHP 通常有内存大小限制,任何 LONGBLOB 或 LONGTEXT 的获取都可能超过该限制。

于 2008-12-03T03:33:59.433 回答