【问题标题】:PL/SQL json_value function gives error for large JSON documentPL/SQL json_value 函数为大型 JSON 文档提供错误
【发布时间】:2020-02-03 02:18:02
【问题描述】:

服务尝试从 JSON 对象中提取角色 ID,但提供了

Error report:
ORA-01460: unimplemented or unreasonable conversion requested
ORA-06512: at line 1801
01460. 00000 -  "unimplemented or unreasonable conversion requested"
*Cause:    
*Action:

代码是

set serveroutput on
declare
    input_data      VARCHAR2(32000);
    lv_role_id     VARCHAR2 (100);
begin
    input_data := '';
    input_data:=input_data||'{';
    input_data:=input_data||'  "roleid": "2945",';
    input_data:=input_data||'  "featureid": "3",';
    input_data:=input_data||'  "category": [';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "31",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "32",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "33",';
    input_data:=input_data||'      "ischecked": true';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "34",';
    input_data:=input_data||'      "ischecked": true';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "35",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "36",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "37",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "38",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "39",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "40",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "41",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "43",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "42",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "44",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "45",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "46",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "47",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "48",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "49",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "50",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "51",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "52",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "53",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "54",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "55",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "56",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "57",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "58",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "59",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "60",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "81",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "314",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "276",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "86",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "72",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "271",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "78",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "383",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "206",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "210",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "384",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "122",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "352",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "307",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "291",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "125",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "236",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "82",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "247",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "234",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "232",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "112",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "66",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "107",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "71",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "73",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "246",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "192",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "273",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "80",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "106",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "195",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "144",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "262",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "118",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "109",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "160",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "272",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "238",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "156",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "178",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "339",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    input_data:=input_data||'    {';
    input_data:=input_data||'      "featureid": "3",';
    input_data:=input_data||'      "id": "277",';
    input_data:=input_data||'      "ischecked": false';
    input_data:=input_data||'    },';
    // input_data:=much more data
    input_data:=input_data||'  ]';
    input_data:=input_data||'}';

    SELECT JSON_VALUE (input_data, '$.roleid' returning number) INTO lv_role_id FROM DUAL;

end;
/

但是,不管其他人可能会怎么想,文档的大小似乎会产生影响。如果我运行以下小得多的 JSON 解析,它会解析该值。

set serveroutput on
declare
    input_data      VARCHAR2(32000);
    lv_role_id     VARCHAR2 (100);
begin
    input_data := '';
    input_data:=input_data||'{';
    input_data:=input_data||'  "roleid": "2945",';
    input_data:=input_data||'  "featureid": "3"';
    input_data:=input_data||'}';

    SELECT JSON_VALUE (input_data, '$.roleid' returning number) INTO lv_role_id FROM DUAL;

end;
/

我尝试获取实际的 JSON 有效负载并通过 lint 验证器运行它,即使是长的也是兼容的。将 JSON 插入表中的 CLOB,然后在该列上运行 SELECT JSON_VALUE 即可。 AskTom 的人说问题是返回一个很大的值,但我认为它在获取一个很大的值时遇到了问题。

【问题讨论】:

  • 两件事 - AskTOM 的家伙每天都在处理这样的问题,所以也许再看看他们的答案,为什么不直接将 input_dat 声明为 CLOB?无需选择表格

标签: json oracle plsql


【解决方案1】:

您的数据库版本似乎有问题。没有提到,所以我建议升级或寻找补丁。我将您的示例简化为有一个添加到文档中的循环,而不是为了便于测试。这是在 db 19.3 中,显示 json input_data 的长度为 31k 并打印预期的消息。

$ sql klrice/klrice

SQLcl: Release 19.2 Production on Fri Oct 04 14:48:32 2019

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

Last Successful login time: Fri Oct 04 2019 14:48:34 -04:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0

SQL> set serveroutput on
SQL>
SQL> declare
        input_data      VARCHAR2(32000);
        lv_role_id     VARCHAR2 (100);
    begin
        input_data := '';
        input_data:=input_data||'{';
        input_data:=input_data||'  "roleid": "2945",';
        input_data:=input_data||'  "featureid": "3",';
        input_data:=input_data||'  "category": [';

       for i in 1..410 loop
       input_data:=input_data||'    {';
       input_data:=input_data||'      "featureid": "3",';
       input_data:=input_data||'      "id": "'|| i ||'",';
       input_data:=input_data||'      "ischecked": false';
       input_data:=input_data||'    },';
       end loop;

       input_data:=input_data||'  ]';
       input_data:=input_data||'}';

       SELECT JSON_VALUE (input_data, '$.roleid' returning number) INTO lv_role_id FROM DUAL;
       dbms_output.put_line('JSON Size:'|| length(input_data));
       dbms_output.put_line('Role:'|| lv_role_id);

   end;
 /
JSON Size:31110
Role:2945


PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • 刚刚在 12.2、18 和 19 中进行了测试,并且可以正常工作。版本 12.1 - 失败。如果我将 input_data 切换到 CLOB,它可以工作!
  • @thatjeffsmith 我认为你是对的。我做了```select * from v$version 并得到:Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production PL/SQL Release 12.1.0.2.0 - Production "CORE 12.1.0.2.0 Production" TNS for Linux:版本 12.1.0.2.0 - 生产 NLSRTL 版本 12.1.0.2.0 - 生产`
  • @Woodsman 很酷,所以你有一个硬修复(升级)或一个简单修复(CLOB!)
  • 不是 Oracle DBA,我不知道从我们的版本升级到下一个版本是困难还是值得。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
相关资源
最近更新 更多