首批通过分布式安全可靠测评,为关键业务系统打造
使用 SELECT 语句调用 UDF 且 UDF 中存在 UPDATE 导致报错 -4007
更新时间:2026-05-19 08:21
问题现象
OceanBase 数据库从 V3.2.3 BP3 版本升级到 V3.2.4 BP8 版本,在 MySQL 租户模式下,通过 SELECT 语句调用包含 DML 语句(如 UPDATE)的 UDF 函数时,执行报错 -4007(OB_NOT_SUPPORTED)。
问题 SQL 结构示例如下:
UPDATE xxxxx_xxxxx_main main
LEFT JOIN (
SELECT DISTINCT xxxxx_xxxxx_sub.RPT_ID,'NOTNULL' AS FLAG
FROM xxxxx_xxxxx_sub
WHERE ALERT_TIME_0 ...
) ...
关键错误日志信息如下:
[2026-03-05 16:15:47.170950] WDIAG [SQL] ob_spi.cpp:265 [15402][0][xxxxx-xxxxx-xxxxx-xxxxx] [lt=5] [dc=0][errcode=-4007] cannot perform a DML operation inside a query(ret=-4007, stmt_type=5, session.is_fast_select()=true)
问题原因
自 OceanBase 数据库 V3.2.4 BP5 版本起,为防止在 Fast Select 路径下嵌套执行 DML 语句导致事务一致性问题(例如报错 Cannot execute statement in a READ ONLY transaction),OceanBase 数据库强制限制了 PL/SQL Cursor 仅支持 SELECT 语句。
任何在 Cursor 上下文中执行的非 SELECT 语句(如 UPDATE、INSERT、DELETE)均会被拦截并返回 -4007 错误。此变更旨在规范 PL/SQL 执行行为,避免潜在的事务异常和执行路径混乱。
适用版本
OceanBase 数据库 V3.2.4 BP5(oceanbase-3.2.4.5-105000012023081513)之前版本。
问题的风险及影响
SQL 执行报错 -4007,导致相关业务逻辑中断。
解决方法
升级到问题已修复版本。目前已修复的版本包含 OceanBase 数据库 V3.2.4 BP5(oceanbase-3.2.4.5-105000012023081513)及之后版本。
规避方式
检查所有涉及 UDF 调用的 PL/SQL 代码,确认是否存在通过
SELECT语句调用包含 DML 语句的函数。将此类调用从
SELECT语句改为其他调用方式。-- 示例中原逻辑(Cursor 中执行 UPDATE - 不支持) OPEN cur FOR UPDATE ...; -- 触发 -4007 -- 将示例中 UPDATE 逻辑移出 Cursor,改用直接执行 BEGIN EXECUTE IMMEDIATE 'UPDATE xxxxx_xxxxx_main main LEFT JOIN (...) sub ON ... SET ...'; -- 绕过 Cursor 限制 END;在升级至 V3.2.4 BP5(oceanbase-3.2.4.5-105000012023081513)或更高版本前,对所有使用 PL/SQL Cursor 的业务逻辑进行兼容性测试,重点验证 UDF 中是否包含 DML 操作。