首批通过分布式安全可靠测评,为关键业务系统打造
OceanBase 数据库 PL 包含 PIVOT、静态 SQL 时,执行报 -4016, Internal error 的原因和解决方法
更新时间:2026-05-29 08:46
问题现象
OceanBase 数据库 PL 包含 PIVOT、静态 SQL 时,执行报错 -4016, Internal error。
示例。
obclient [SYS]> BEGIN
FOR X IN (SELECT ID FROM LBORGANIZATION WHERE ORGTYPE = 6) LOOP
INSERT INTO wcl_yxry_fgs
(MON, YYB, WCL_HJ, WCL_BY)
SELECT MON,
X.ID YYB,
NVL(WCZ_HJ, 0) / MBZ_HJ * 100 WCL_HJ,
NVL(WCZ_BY, 0) / MBZ_BY * 100 WCL_BY
FROM (SELECT MON, ZBDM, ZBZ
FROM TRYZBTJ T
WHERE T.ZBDM IN
('YXGT_MBZ_HJ', 'YXGT_WCZ_HJ', 'YXGT_WCZ_BY', 'YXGT_MBZ_BY')
AND MON BETWEEN 202401 AND 202407
AND YYB IN (SELECT ID
FROM LBORGANIZATION
START WITH ID = X.ID
CONNECT BY PRIOR ID = FID)) T
PIVOT(SUM(ZBZ)
FOR ZBDM IN('YXGT_MBZ_HJ' AS MBZ_HJ,
'YXGT_WCZ_HJ' AS WCZ_HJ,
'YXGT_MBZ_BY' AS MBZ_BY,
'YXGT_WCZ_BY' AS WCZ_BY));
END LOOP;
END;
/
ORA-00600: internal error code, arguments: -4016, Internal error
at anonymous block , line : 3, col : 5
关键日志信息。
[24-09-25 14:31:58.166392] WARN [PL] deep_copy (ob_pl_type.cpp:1806) [593517][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=22] [dc=0] streaming cursor can not be copy(src={id:-1, is_explicit:true, for_update:false, has_hidden_rowid:false, is_streaming:true, isopen:true, fetched:true, fetched_with_row:true, rowcount:1, current_position:-1, current_row:{row:[{"NUMBER":"6"}, {"NUMBER":"1608"}], projector:[1]}, first_row:{row:null, projector:null}, last_row:{row:null, projector:null}, in_forall:false, save_exception:false, forall_rollback:false, read_uncommited:false, trans_id:{hash:0, inc:0, addr:"0.0.0.0", t:0}, bulk_rowcount:[], bulk_exceptions:[], spi_cursor:0xfff1ccb22820, cursor_flag:0, ref_count:1, is_scrollable:false, last_execute_time:1727245918166352}, ret=-4016)
[2024-09-25 14:31:58.166419] WARN [PL] deep_copy_cursor (ob_pl_user_type.cpp:753) [593517][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=25] [dc=0] fail to exec dest_cursor->deep_copy(*src_cursor, &allocator)(ret=-4016)
问题原因
该报错为产品缺陷,PIVOT 在包含静态 SQL 的 PL 执行时参数化存在问题,导致报错 -4016。
问题的风险及影响
PL 执行报错。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V3.x、V4.x 版本。
解决方法及规避方式
解决方法:
升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库企业版本 V4.2.1 BP8(oceanbase-4.2.1.8-108000052024072217)版本、V4.2.5(oceanbase-4.2.5.0-100000082024102022)版本。
规避方式:
将静态 SQL 改为动态 SQL 可绕过,示例如下。
DECLARE sql_str varchar2(1000); BEGIN sql_str := 'INSERT INTO wcl_yxry_fgs (MON, YYB, WCL_HJ, WCL_BY) SELECT MON, :1 YYB, 100 WCL_HJ, 100 WCL_BY FROM (SELECT MON, ZBDM, ZBZ FROM TRYZBTJ T WHERE T.ZBDM IN (''YXGT_MBZ_HJ'', ''YXGT_WCZ_HJ'', ''YXGT_WCZ_BY'', ''YXGT_MBZ_BY'') AND MON BETWEEN 202401 AND 202407 AND YYB IN (SELECT ID FROM LBORGANIZATION START WITH ID = :2 CONNECT BY PRIOR ID = FID)) T PIVOT(SUM(ZBZ) FOR ZBDM IN(''YXGT_MBZ_HJ'' AS MBZ_HJ, ''YXGT_WCZ_HJ'' AS WCZ_HJ, ''YXGT_MBZ_BY'' AS MBZ_BY, ''YXGT_WCZ_BY'' AS WCZ_BY))'; FOR X IN (SELECT ID FROM LBORGANIZATION WHERE ORGTYPE = 6) LOOP execute immediate sql_str using x.id, x.id; END LOOP; END; /