Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PL/SQL中处理JSON数组_Sql_Json_Oracle_Plsql_Oracle19c - Fatal编程技术网

在PL/SQL中处理JSON数组

在PL/SQL中处理JSON数组,sql,json,oracle,plsql,oracle19c,Sql,Json,Oracle,Plsql,Oracle19c,我在myjson表doc列中存储了一个JSON文档 { "totalResultsCount": 19, "geonames": [ { "geonameId": 2593109, "fcode": "ADM1" }, { "geonameId": 3336899, "fcode"

我在myjson表doc列中存储了一个JSON文档

{
  "totalResultsCount": 19,
  "geonames": [
    {
      "geonameId": 2593109,
      "fcode": "ADM1"
    },
    {
      "geonameId": 3336899,
      "fcode": "ADM1"
    }, ...
当我运行查询时

select j.doc.geonames.geonameId from myjson j where j.doc.geonames.fcode  like '%ADM1%';
我得到一个ID数组

[2593109,3336899,3114710,2521383,3336903,2593110,3336898,3336900,2593111,3336901,2519582,2593112,3336902,3336897,3117732,6362988,2513413,3115609,2593113]

如何读取此数组并使用FOR循环打印每个ID?

为此,我们可以使用JSON_表

SQL/JSON函数JSON_表将特定的JSON数据投影到各种SQL数据类型的列中。您可以使用它将JSON文档的一部分映射到一个新的虚拟表的行和列中,您也可以将其视为一个内联视图

编辑 使用
JSON_表
作为for循环中的源

begin
 for i in (SELECT geonameid
             FROM json_table('[2593109,3336899,3114710,2521383,3336903,2593110,3336898,3336900,2593111,3336901,2519582,2593112,3336902,3336897,3117732,6362988,2513413,3115609,2593113]'
                             ,'$[*]' columns(geonameId NUMBER path '$')))
 loop
   dbms_output.put_line('Id: '||i.geonameid);
 end loop;
end;
/
还是不确定你是否想要这个


Reference

您可以在Oracle的SQL中使用包含交叉联接的
JSON_TABLE()
函数,以便解析
产品
fcode
的各个列值,并分别在选择列表和WHERE条件中使用它们,如下所示:

SELECT ROW_NUMBER() OVER (ORDER BY 1) AS row_id, js.product 
  FROM myjson
 CROSS JOIN
       JSON_TABLE( 
                 doc, '$.geonames[*]' COLUMNS (
                                               product VARCHAR(100) PATH '$.geonameId',
                                               fcode   VARCHAR(100) PATH '$.fcode'
                                              )
        ) js
  WHERE js.fcode = 'ADM1' 

更新:根据您对返回值数组赋值需求的评论,评估以下内容:

SQL> SET SERVEROUTPUT ON

SQL> DECLARE
  json_array_t OWA.VC_ARR;
BEGIN
  FOR c IN
  (
   SELECT ROW_NUMBER() OVER (ORDER BY 1) - 1 AS row_id, js.product 
     FROM myjson
    CROSS JOIN JSON_TABLE( 
                          doc, '$.geonames[*]' COLUMNS (
                                               product VARCHAR(100) PATH '$.geonameId',
                                               fcode   VARCHAR(100) PATH '$.fcode'
                                               )
                ) js
    WHERE js.fcode = 'ADM1' )
  LOOP    
    json_array_t(c.row_id) := c.product;
    DBMS_OUTPUT.PUT_LINE( 'value for json_array_t('||c.row_id||') is '||json_array_t(c.row_id) );
  END LOOP;
END;
/

更新2:您可以使用原始查询设置数组值,然后根据需要使用FOR循环提取该数组的所有成员。最后:

DECLARE
  l_str          VARCHAR2(32767);
  l_top_obj      JSON_OBJECT_T;
  l_dept_arr     JSON_ARRAY_T;
  l_dept_obj     JSON_OBJECT_T;
  l_emp_arr      JSON_ARRAY_T;
  l_emp_obj      JSON_OBJECT_T;
BEGIN
  SELECT j.doc 
    INTO l_str
    FROM myjson j 
   WHERE j.doc.geonames.fcode LIKE '%ADM1%';    
  
  l_top_obj := JSON_OBJECT_T(l_str);
  l_dept_arr := l_top_obj.get_array('geonames');
  
  FOR i IN 0 .. l_dept_arr.get_size - 1 
  LOOP
    l_dept_obj := TREAT(l_dept_arr.get(i) AS JSON_OBJECT_T);
    DBMS_OUTPUT.PUT_LINE('index  : '||i||' - geonameId : ' || l_dept_obj.get_number('geonameId'));
  END LOOP;
END;
/

感谢您的回复。我已经实现了这个JSON_表。但是,我真的想知道如何使用FOR循环。像myarray json_array_t:=[1,2,3];对于0到myarray.size()循环。。。。等等,我真的不明白,如果已经实现了json_表,就在for循环中使用它。为什么还要使用json_数组?json_表使您能够将json转换为列值,就像表一样。在我问题中的第一个Select查询中,我得到了一个值数组。如果我可以用“select into var from table”将该数组分配给一个变量,那么我就有了我的数组对象。然后我可以使用数组操作,或者使用循环遍历,或者任何其他操作。使用json_表可能是一个不错的选择,但我想了解数组的用法。感谢您的回复。我已经实现了这个JSON_表。但是,我真的想知道如何使用FOR循环。像myarray json_array_t:=[1,2,3];对于0到myarray.size()循环。。。。等等。我需要在循环中一次一个地将ID传递给另一个函数。唔@SureshVeeranala,不客气,您可以签出编辑。我们可以不使用表来完成吗?我只想将数组存储在一个变量中,并对该变量执行数组操作。@BarbarosÖzhan:我真的很感谢你的努力,尽管我不是OP,但我从这个答案+1中获得了很多学习点。谢谢。我同意@Sujitmohanty30。答案非常翔实。
DECLARE
  l_str          VARCHAR2(32767);
  l_top_obj      JSON_OBJECT_T;
  l_dept_arr     JSON_ARRAY_T;
  l_dept_obj     JSON_OBJECT_T;
  l_emp_arr      JSON_ARRAY_T;
  l_emp_obj      JSON_OBJECT_T;
BEGIN
  SELECT j.doc 
    INTO l_str
    FROM myjson j 
   WHERE j.doc.geonames.fcode LIKE '%ADM1%';    
  
  l_top_obj := JSON_OBJECT_T(l_str);
  l_dept_arr := l_top_obj.get_array('geonames');
  
  FOR i IN 0 .. l_dept_arr.get_size - 1 
  LOOP
    l_dept_obj := TREAT(l_dept_arr.get(i) AS JSON_OBJECT_T);
    DBMS_OUTPUT.PUT_LINE('index  : '||i||' - geonameId : ' || l_dept_obj.get_number('geonameId'));
  END LOOP;
END;
/