在PLSQL 12.1中循环遍历JSON数组

3

我有一个存储在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就足够了。 - Barbaros Özhan
1个回答

6
您可以直接使用JSON_TABLE()函数与Oracle DB 12.1.0.2版本一起使用SQL,如下所示。
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'
                                            )
                                  )
          );

演示

如果确实需要使用 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; 
/

示例2


你能像我示例中那样将JSON声明为变量并运行代码吗? 当我尝试这样做时,出现ORA-00900:无效的SQL语句错误。 对我来说,这非常关键。整个JSON必须在varchar变量内部。 - David
我已经添加了 PL/SQL 的案例 @David - Barbaros Özhan
我觉得这对我来说有点复杂,有没有更简单的方法呢? 比如在PL/SQL中直接使用,不需要使用SQL函数,你可以通过以下方式获取数组: arrayCars := JSON_QUERY(JsonArray, '$.Cars'); 然后我只需要循环遍历该数组,并将这些变量用于某些操作。假设我们有一个testVar varchar,并在循环中将所有变量添加到它里面。 testVarchar:=testVarchar+Honda; 然后 testVarchar:=testVarchar+red; 然后 testVarchar:=testVarchar+Toyota; 然后 testVarchar:=testVarchar+green; - David
我的意思是我需要一些循环操作,在这个过程中我可以做一些事情并使用本田的变量,然后再做一些事情并使用丰田的变量。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接