You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle PL/SQL无法从JSON对象取数组赋值表对象类型报错求助

问题:Oracle PL/SQL中JSON数组转自定义表类型报错ORA-00904

错误信息

ORA-06550: line 14, column 12:
PL/SQL: ORA-00904: "L_EMP_ARR": invalid identifier
ORA-06550: line 7, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

用户代码

自定义类型声明

CREATE OR REPLACE TYPE XX_OUTPUT_OBJ 
AS
OBJECT(
    EMP_ID      NUMBER,
    NAME        VARCHAR2(50),
    SALARY      NUMBER
);

CREATE OR REPLACE TYPE XX_INPUT_TYPE
IS TABLE OF XX_OUTPUT_OBJ;

PL/SQL执行块

DECLARE
  input_type    XX_INPUT_TYPE;
  l_obj JSON_OBJECT_T := JSON_OBJECT_T('{"supplier":"name","items":[{"empid":109, "name":"raj","salary":111},{"empid":110, "name":"raj1","salary":222}] }');
  l_emp_arr     JSON_ARRAY_T;
BEGIN
    l_emp_arr := l_obj.get_array('items');
  SELECT XX_OUTPUT_OBJ(
           emp_id,
           name,
           salary
         )
  BULK COLLECT INTO input_type
  FROM   JSON_TABLE(
           l_emp_arr.stringify,
           '$[*]'
           COLUMNS (
             emp_id NUMBER       PATH '$.empid',
             name   VARCHAR2(50) PATH '$.name',
             salary NUMBER       PATH '$.salary'
           )
         );

  FOR i IN 1 .. input_type.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(
      input_type(i).emp_id || ', '
      || input_type(i).name || ','
      || input_type(i).salary
    );
  END LOOP;
END;

错误原因

SQL语句中的JSON_TABLE无法直接引用PL/SQL变量l_emp_arr——SQL引擎与PL/SQL引擎相互独立,必须通过绑定变量传递PL/SQL变量到SQL上下文,或者直接在JSON_TABLE中使用原始JSON对象的路径,跳过中间变量传递环节。

解决方案

方案1:直接引用原始JSON对象的路径

无需提前提取JSON_ARRAY_T,直接在JSON_TABLE中指定数组路径'$.items[*]':

DECLARE
  input_type    XX_INPUT_TYPE;
  l_obj JSON_OBJECT_T := JSON_OBJECT_T('{"supplier":"name","items":[{"empid":109, "name":"raj","salary":111},{"empid":110, "name":"raj1","salary":222}] }');
BEGIN
  SELECT XX_OUTPUT_OBJ(
           emp_id,
           name,
           salary
         )
  BULK COLLECT INTO input_type
  FROM   JSON_TABLE(
           l_obj.stringify,
           '$.items[*]'
           COLUMNS (
             emp_id NUMBER       PATH '$.empid',
             name   VARCHAR2(50) PATH '$.name',
             salary NUMBER       PATH '$.salary'
           )
         );

  FOR i IN 1 .. input_type.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(
      input_type(i).emp_id || ', '
      || input_type(i).name || ','
      || input_type(i).salary
    );
  END LOOP;
END;
/

方案2:使用绑定变量传递PL/SQL变量

先将l_emp_arr转为字符串变量,再通过绑定变量:l_arr_str传递给JSON_TABLE:

DECLARE
  input_type    XX_INPUT_TYPE;
  l_obj JSON_OBJECT_T := JSON_OBJECT_T('{"supplier":"name","items":[{"empid":109, "name":"raj","salary":111},{"empid":110, "name":"raj1","salary":222}] }');
  l_emp_arr     JSON_ARRAY_T;
  l_arr_str     VARCHAR2(4000);
BEGIN
    l_emp_arr := l_obj.get_array('items');
    l_arr_str := l_emp_arr.stringify;

  SELECT XX_OUTPUT_OBJ(
           emp_id,
           name,
           salary
         )
  BULK COLLECT INTO input_type
  FROM   JSON_TABLE(
           :l_arr_str,
           '$[*]'
           COLUMNS (
             emp_id NUMBER       PATH '$.empid',
             name   VARCHAR2(50) PATH '$.name',
             salary NUMBER       PATH '$.salary'
           )
         );

  FOR i IN 1 .. input_type.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE(
      input_type(i).emp_id || ', '
      || input_type(i).name || ','
      || input_type(i).salary
    );
  END LOOP;
END;
/

说明

方案1更简洁,减少中间变量;方案2保留了先提取JSON数组的逻辑,适合需要对数组进行额外预处理的场景。

内容的提问来源于stack exchange,提问作者mu shaikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:51:32