当从MySQL中选择LONGTEXT列时,在CRecordset中出现“内存不足”异常
我正在使用CODBCRecordset(在CodeProject上找到的类)在具有39列的表中查找单个记录。如果没有找到记录,那么对CRecordset :: Open的调用就可以了。如果一条记录符合条件,那么当调用CRecordset :: Open时,会出现Out of Memory异常。我选择查询中的所有列(如果我更改查询以仅选择具有相同where子句的列中的一个,则不会有例外)。当从MySQL中选择LONGTEXT列时,在CRecordset中出现“内存不足”异常
我认为这是由于CRecordset的一些限制,但我找不到任何限制。该表只有39列。
有没有人遇到这个问题?如果是这样,你有解决方案吗?
这是一个使用Visual Studio 6.0的MFC项目,如果它有任何区别的话。
这里的查询(此格式,因此沃尔德显示不使用滚动条):
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'
复制并粘贴到我的查询浏览器给我只有一个结果。
更多信息:
注释掉select语句中除id以外的每一列。执行查询并且不会例外。
然后,我系统地通过并取消注释每一列,然后在每个取消注释之间重新运行查询。
当我取消注释评论列,然后我得到错误。
这被定义为以下(使用MySQL):LONGTEXT
阅读Pax的回应。它让你对问题发生的原因有了很好的理解。
解决方法:
如果定义为(文字,LONGTEXT等)的字段为空(也可能是空的)才会发生这种错误。如果字段中有数据,那么它只会分配字段中数据的大小而不是最大大小(从而导致错误)。
所以,如果有一种情况下,你绝对必须有这些大的领域。这是一个潜在的解决方案:
- 给该字段在数据库中的默认值。 (即
'<blank>'
) - 然后当显示值;如果您找到默认值,则传递NULL /空。
- 然后更新该值;如果发现NULL /空,则传递默认值。
我们是否可以假设你的意思是你调用C ODBC记录::打开(),是吗?或者更准确地说,是这样的:响应后
CDatabase db;
db.Open (NULL,FALSE,FALSE,"ODBC;",TRUE);
CODBCRecordSet rs (&db);
rs.Open ("select blah, blah, blah from ...");
编辑:
有与可能通过检索无效的字段长度引起的各种ODBC驱动程序的一些已知的bug。请参阅以下链接:
- http://forums.microsoft.com/msdn/showpost.aspx?postid=2700779&siteid=1
- https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=296391
这尤其是一个似乎已经因为CRecordset的将分配大到足以容纳领域的缓冲。由于列返回长度为零,因此它被解释为最大32位大小(〜2G),而不是最大8位大小(255字节)。不用说,它不能为该领域分配足够的内存。
微软已经承认这是一个问题,看看这些解决办法:问题的附加物之后
编辑:
所以,鉴于你的MySQL字段是LONGTEXT,它看起来CRecordSet正在尝试为其分配最大可能的尺寸(2G)。你真的需要2场演出评论领域?打字速度为80 wpm时,6cpw将在7年后打字员填补该字段,每天24小时工作,无需休息:-)。
查看数据库中的所有列以查看它们是否具有适当的数据类型可能是一种有用的练习。我并不是说你不能有有一个2G列,只是你应该确定它是必要的,尤其是考虑到当前的ODBC类不适用于大的字段。
我第二个Pax的建议是,这个错误是由于试图分配一个足够容纳最大LONGTEXT的缓冲区。客户端在获取数据之前不知道数据的大小。
LONGTEXT确实比您在大多数应用中所需要的要大得多。考虑使用MEDIUMTEXT(最大尺寸为16MB)或者仅使用TEXT(最大尺寸为64KB)。
PHP数据库接口也有类似的问题。 PHP通常具有内存大小限制,任何对LONGBLOB或LONGTEXT的读取都可能超过该限制。
是的。然后,当我通过代码进行调试时,它会在CODBCRecordset :: Open函数的CRecordset :: Open命令中引发异常。 – 2008-12-02 06:22:38