Teradata用regexp拆分单单元格报9134缓冲区超限问题咨询
Teradata 9134缓冲区超限报错解决方法
问题根因
Teradata内置正则系列函数(包括RegExp_Split_To_Table、regexp_replace、regexp_substr)默认最大仅支持64KB长度的输入内容,即使你将字段显式转为CLOB传入,函数内部会默认隐式转换为VARCHAR(64000)处理,内容超过该长度就会触发9134报错。你两次报错的区别仅为:第一次是拆分后输出的Token超过了你定义的VARCHAR(35000)长度限制,第二次是输入的CLOB内容超过了函数默认64KB的输入缓冲区限制。
可行解决方案
方案1:高版本Teradata(17.10+)用CLOB重载版本
17.10及以上版本的Teradata新增了支持CLOB输入输出的RegExp_Split_To_Table重载,直接修改返回值类型为CLOB即可:
WITH t AS ( SELECT MHKAUDITLOGINTERNALID AS id, CAST(MHK_CONTENT AS CLOB) AS MHK_CONTENT FROM vcoreMEDHOK_MHK_Audit AS ma WHERE CAST(ma.AUDITDATETIME AS DATE) >= '2021/08/15' ) SELECT DISTINCT id, REGEXP_REPLACE(Token, '<b>|<\/b>', '') AS cleaned_content FROM TABLE ( RegExp_Split_To_Table(t.id, t.MHK_CONTENT, '<\/b>', 'i') RETURNS (id BIGINT, TokenNum INT, Token CLOB CHARACTER SET LATIN) ) AS dt
方案2:低版本Teradata用递归CTE手动拆分
如果你的Teradata版本低于17.10,用递归CTE逐段拆分CLOB,避开正则函数的缓冲区限制:
WITH RECURSIVE split_cte (id, content, remaining, pos) AS ( SELECT MHKAUDITLOGINTERNALID AS id, CAST('' AS CLOB) AS content, CAST(MHK_CONTENT AS CLOB) AS remaining, 1 AS pos FROM vcoreMEDHOK_MHK_Audit WHERE CAST(AUDITDATETIME AS DATE) >= '2021/08/15' UNION ALL SELECT id, -- 提取当前分隔符前的内容 SUBSTRING(remaining FROM 1 FOR REGEXP_INSTR(remaining, '<\/b>', 1, 1, 0, 'i') - 1) AS content, -- 剩余未拆分的内容 SUBSTRING(remaining FROM REGEXP_INSTR(remaining, '<\/b>', 1, 1, 1, 'i')) AS remaining, pos + 1 AS pos FROM split_cte WHERE REGEXP_INSTR(remaining, '<\/b>', 1, 1, 0, 'i') > 0 ) SELECT DISTINCT id, REGEXP_SUBSTR(content, '.*<b>\K.*') AS cleaned_content FROM split_cte WHERE content <> '' -- 拆分层级限制,避免死循环,可根据实际最大拆分段数调整 AND pos < 1000
额外优化建议
- 先确认实际拆分分隔符:你第一段SQL的注释写的是按
</b>拆分,但实际分隔符参数写的是<BR/>,先对齐业务逻辑,避免生成超过预期的超长Token - 如果确认拆分后单段内容不超过32000字符,可将返回的CLOB再转为
VARCHAR(32000)提升后续处理性能 - 可先加过滤条件
WHERE CHARACTER_LENGTH(MHK_CONTENT) < 64000跑通逻辑,再单独处理超长内容的行,缩小问题排查范围
内容的提问来源于stack exchange,提问作者Tekno Joe
相关产品推荐
相关产品推荐

