循环遍历 PLSQL 12.1 中的 JSON 数组

Posted

技术标签:

【中文标题】循环遍历 PLSQL 12.1 中的 JSON 数组【英文标题】:Loop through JSON array in PLSQL 12.1 【发布时间】:2021-01-25 19:20:03 【问题描述】:

我在 varchar 中有 JSON 数组

DECLARE
 JsonArray varchar2(1000);
 arrayCars varchar2(1000);      
BEGIN
  JsonArray :="Cars": ["name":"Honda", "color":"red" ,
                        "name":"Toyota", "color":"green"] 
  SELECT JSON_QUERY(JsonArray, '$.Cars') into arrayCars FROM dual;
END;
/

现在如果我打印出 arrayCars 我会得到

["name":"Honda","color":"red","name":"Toyota","color":"green"]

但是我怎样才能遍历这个 Cars 数组并分别打印出它的组件(访问它们)?

【问题讨论】:

PL/SQL 不需要提取所需的部分,使用 SQL 就足够了。 【参考方案1】:

您可以直接使用SQLJSON_TABLE() 功能,从Oracle DB 12.1.0.2 版本开始,例如

WITH t(arrayCars) AS
(
 SELECT JSON_QUERY('"Cars": ["name":"Honda", "color":"red" , 
                              "name":"Toyota", "color":"green"] ', '$.Cars') 
   FROM dual
)
SELECT name, color
  FROM t
 CROSS JOIN JSON_TABLE(arrayCars,
                       '$' COLUMNS(NESTED PATH '$[*]'
                                    COLUMNS(
                                            name  VARCHAR2(100) PATH '$.name',
                                            color VARCHAR2(100) PATH '$.color'
                                            )
                                  )
          );

Demo

如果你真的需要使用PL/SQL,那么考虑创建一个返回类型为SYS_REFCURSOR的函数比如

CREATE OR REPLACE FUNCTION Get_Cars RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  JsonArray   VARCHAR2(1000);
  arrayCars   VARCHAR2(1000);
  v_sql       VARCHAR2(32767);  
BEGIN
  JsonArray :='"Cars": ["name":"Honda", "color":"red" ,
                         "name":"Toyota", "color":"green"] ';
  arrayCars := JSON_QUERY(JsonArray, '$.Cars');
  DBMS_OUTPUT.PUT_LINE(arrayCars);

  v_sql := 
  'SELECT name,color
     FROM dual
    CROSS JOIN JSON_TABLE(:Cars,
                          ''$'' COLUMNS(NESTED PATH ''$[*]''
                                      COLUMNS(
                                              name  VARCHAR2(100) PATH ''$.name'',
                                              color VARCHAR2(100) PATH ''$.color''
                                              )
                                    )

            )';
  OPEN v_recordset FOR v_sql USING arrayCars;
  RETURN v_recordset;
END;
/

然后从 SQL Developer 的控制台调用

SQL> DECLARE
    result SYS_REFCURSOR;
BEGIN
   :result := Get_Cars;
END;
/

SQL> PRINT result ;

编辑(您的最后一条评论):

或者,您可以使用简单的隐式循环,例如

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  v_name   VARCHAR2(1000);
  v_color  VARCHAR2(1000);
BEGIN
   FOR c IN (
             SELECT name,color
               FROM JSON_TABLE('"Cars": ["name":"Honda", "color":"red" ,
                                          "name":"Toyota", "color":"green"] ',
                                    '$' COLUMNS(NESTED PATH '$.Cars[*]'
                                                COLUMNS(
                                                        name  VARCHAR2(100) PATH '$.name',
                                                        color VARCHAR2(100) PATH '$.color'
                                                        )
                                                )
                               )
            )
   LOOP
     v_name  := c.name;
     v_color := c.color; 
     DBMS_OUTPUT.PUT_LINE(v_name||'  '||v_color);
   END LOOP;                            
END; 
/

Demo2

【讨论】:

您可以像我的示例中那样使用声明为变量的 JSON 来运行您的代码吗?当我尝试这个时,我得到 ORA-00900: invalid SQL statement 这对我来说很重要。整个 JSON 必须在 varchar 变量中 我已经为 PL/SQL @David 添加了案例 我觉得这对我来说有点复杂,有什么方法可以做的更简单一些吗?如果没有 sql 函数,直接在 plsql 中,例如在这里你会得到数组 arrayCars := JSON_QUERY(JsonArray, '$.Cars');然后我只需要遍历该数组并将这些变量用于某些东西。假设我们有一些 testVar varchar 并在循环内添加所有变量。 testVarchar:=testVarchar+本田;然后 testVarchar:=testVarchar+red;然后 testVarchar:=testVarchar+丰田;然后 testVarchar:=testVarchar+green; 我的意思是我需要一些循环动作,我可以做一些事情并使用本田变量,然后做一些事情并使用丰田变量。

以上是关于循环遍历 PLSQL 12.1 中的 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章

循环遍历带有更新字段条件的游标 [PLSQL]

如何遍历 Oracle PLSQL 中的分隔列表

尝试循环通过 XML 提取 PLSQL 中的值

我的 PLSQL 触发器没有循环遍历表

plsql developer v12.1的使用

Kendo UI 循环遍历 ListView 模板中 Json 中的集合