基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
SQL 中使用 utl_raw.cast_to_raw 函数无法同时使用并行
更新时间:2026-05-15 09:06
适用版本
OceanBase 数据库 V2.x、V3.x 版本。
问题描述
OceanBase 数据库 Oracle 租户,通过 utl_raw.cast_to_raw 函数获取特定列的十六进制值,却发现此操作会使得语句的并行失效。
obclient [SYS]> explain select /*+parallel(a,16)*/ utl_raw.cast_to_raw(col_value) from u_lxl.code_varchar2_gbk a\G
*************************** 1. row ***************************
Query Plan: ==============================================
|ID|OPERATOR |NAME|EST. ROWS|COST |
----------------------------------------------
|0 |EXCHANGE IN REMOTE | |65537 |27790|
|1 | EXCHANGE OUT REMOTE| |65537 |25351|
|2 | TABLE SCAN |A |65537 |25351|
==============================================
Outputs & filters:
-------------------------------------
0 - output([SYS.UTL_RAW.CAST_TO_RAW(A.COL_VALUE)]), filter(nil)
1 - output([SYS.UTL_RAW.CAST_TO_RAW(A.COL_VALUE)]), filter(nil)
2 - output([SYS.UTL_RAW.CAST_TO_RAW(A.COL_VALUE)]), filter(nil),
access([A.COL_VALUE]), partitions(p0)
从上述执行计划可以看得到,并行的 hint 并未生效。
问题原因
OceanBase 数据库的限制。
解决方法
将原来的 UTL_RAW.CAST_TO_RAW 函数替换为 HEXTORAW,相应执行计划如下。
obclient [SYS]> explain select /*+parallel(a,16)*/ hextoraw(col_value) from u_lxl.code_varchar2_gbk a\G
*************************** 1. row ***************************
Query Plan: =================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
-------------------------------------------------
|0 |PX COORDINATOR | |65537 |27790|
|1 | EXCHANGE OUT DISTR|:EX10000|65537 |25351|
|2 | PX BLOCK ITERATOR| |65537 |25351|
|3 | TABLE SCAN |A |65537 |25351|
=================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(HEXTORAW(A.COL_VALUE))]), filter(nil)
1 - output([INTERNAL_FUNCTION(HEXTORAW(A.COL_VALUE))]), filter(nil), dop=16
2 - output([A.COL_VALUE]), filter(nil)
3 - output([A.COL_VALUE]), filter(nil),
access([A.COL_VALUE]), partitions(p0)
需要注意的是,原来 UTL_RAW.CAST_TO_RAW 仅能处理转换后长度为 4000 的字符串,而 HEXTORAW 则无此限制。
utl_raw.cast_to_raw函数,转换后长度为 4000 的情况,语句可正常执行。obclient [SYS]> select length(str), length(utl_raw.cast_to_raw(str)) from (select 'b'||lpad('a',1998,'a')||'b' str from dual); +-------------+----------------------------------+ | LENGTH(STR) | LENGTH(UTL_RAW.CAST_TO_RAW(STR)) | +-------------+----------------------------------+ | 2000 | 4000 | +-------------+----------------------------------+utl_raw.cast_to_raw函数,转换后长度超出 4000,将触发语句报错。obclient [SYS]> select length(str), length(utl_raw.cast_to_raw(str)) from (select 'b'||lpad('a',1999,'a')||'b' str from dual); ORA-06502: PL/SQL: numeric or value error: raw variable length too longHEXTORAW函数则并没有这样的问题。obclient [SYS]> select length(str), length(rawtohex(str)) from (select 'b'||lpad('a',1999,'a')||'b' str from dual); +-------------+-----------------------+ | LENGTH(STR) | LENGTH(RAWTOHEX(STR)) | +-------------+-----------------------+ | 2001 | 4002 | +-------------+-----------------------+