HrQueryAllRows方法中MAPI_E_TABLE_TOO_BIG错误的成因与解决
MAPI_E_TABLE_TOO_BIG (80040403) 错误排查:PR_ANR限制在GAL搜索中的异常情况
在为MAPI表(IMAPITable)设置PR_ANR限制匹配GAL账户时,仅当输入字符串为"x"或"s"时触发MAPI_E_TABLE_TOO_BIG(十六进制80040403)错误,但Outlook GAL搜索框输入这两个词时结果有限(s对应54条,x对应0条),对此错误提示存在困惑。
简化后的C++代码如下:
//SRestriction setup SRestriction pRestop = {}; SRestriction pPropRes[3] = {}; SPropValue sPropValue[2] = {}; //RES_AND // RES_PROP(1) // RES_PROP(2) //RES_AND pRestop.rt = RES_AND; pRestop.res.resAnd.cRes = 3; pRestop.res.resAnd.lpRes = &pPropRes[0]; //RES_Property -> First pPropRes[0].rt = RES_PROPERTY; pPropRes[0].res.resProperty.ulPropTag = PR_ANR_W; sPropValue[0].ulPropTag = PR_DISPLAY_NAME_W; sPropValue[0].Value.lpszW = tmp1; //first string pPropRes[0].res.resProperty.lpProp = &sPropValue[0]; //RES_Property -> Second pPropRes[1].rt = RES_PROPERTY; pPropRes[1].res.resProperty.ulPropTag = PR_ANR_W; sPropValue[1].ulPropTag = PR_DISPLAY_NAME_W; sPropValue[1].Value.lpszW = tmp2; //second string pPropRes[1].res.resProperty.lpProp = &sPropValue[1]; //tmp1 can be equal to tmp2 enum { accPR_DISPLAY_NAME_W, accPR_SMTP_ADDRESS_W, accNUM_COLS }; static SizedSPropTagArray(accNUM_COLS, accCols) = { accNUM_COLS, PR_DISPLAY_NAME_W, PROP_TAG(PT_UNICODE, 0x39FE)}; // Initialize MAPI, Log on to MAPI, Open the Address Book... // Open GAL address book, Get content table(pHTable), // Query phTable if (FAILED(hRes = HrQueryAllRows(pHTable, (LPSPropTagArray) &accCols, &pRestop, NULL, 0L, &pRows))) goto Cleanup; //this is where the error raised
错误原因分析
- Restriction构造错误:代码中
RES_AND的cRes设置为3,但仅初始化了pPropRes[0]和pPropRes[1]两个限制条件,第三个pPropRes[2]是未初始化的垃圾数据。这会导致MAPI执行的查询逻辑完全不符合预期,可能匹配到大量无效条目,触发结果集过大的错误。 - PR_ANR使用逻辑偏差:PR_ANR是自动名称解析属性,原生支持对联系人的多个字段(如显示名、邮箱、姓氏等)进行模糊匹配。但代码中用
AND关联两个PR_ANR条件,这和Outlook搜索框的单条件匹配逻辑完全不同,可能产生意外的查询结果。 - HrQueryAllRows的局限性:该函数会一次性拉取所有匹配的行数据,当结果集超过Exchange或MAPI服务端的默认阈值时,就会返回
MAPI_E_TABLE_TOO_BIG。而Outlook搜索框采用分页加载机制,不会一次性请求所有结果,因此不会触发该错误。
处理方案
- 修正Restriction计数:将
pRestop.res.resAnd.cRes的值改为2,与实际初始化的限制条件数量一致,避免未初始化数据干扰查询逻辑。 - 调整PR_ANR查询逻辑:如果需要匹配包含多个关键词的条目,应使用
RES_OR逻辑关联条件;或者直接使用单个PR_ANR条件(因为ANR本身支持多字段模糊匹配),不要用AND叠加多个ANR限制。 - 替换为分页查询:放弃使用
HrQueryAllRows,改用IMAPITable的QueryRows方法分批次获取数据。步骤如下:- 调用
SetColumns设置需要返回的属性列; - 循环调用
QueryRows,每次指定获取的行数(如100条),直到返回的行数为0,完成所有数据的拉取。
- 调用
内容的提问来源于stack exchange,提问作者Fin Chien
相关产品推荐
相关产品推荐

