powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / распарсить json(глубина не известна), залить в таблицу
24 сообщений из 24, страница 1 из 1
распарсить json(глубина не известна), залить в таблицу
    #39635525
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.

Есть json содержащий иерархию каталогов.
С течением времени depth может меняться, ключи известны: "name", "subfolders".

Мне передают этот json, я должен распарсить его и залить в табличку с такой структурой:
dir number
, dir_parent number
,description varchar2

Не врубаюсь как это сделать, если глубина заведомо неизвестна.

Натолкните на мысль или поделитесь примером, пожалуйста.

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635528
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
israelshamir,

Пример JSONа приведи.

SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635529
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
{
    "name": "root_folder",
    "subfolders": [
        {
            "name": "folder1",
            "subfolders": [
                {
                    "name": "folder1_1",
                    "subfolders": []
                },
                {
                    "name": "folder1_2",
                    "subfolders": [
                        {
                            "name": "folder1_2_1",
                            "subfolders": []
                        }
                    ]
                }
            ]
        },
        {
            "name": "folder2",
            "subfolders": []
        },
        {
            "name": "folder3",
            "subfolders": []
        }
    ]
}
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635538
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
israelshamir,
даже лень писать. либо рекурсивный with либо рекурсивная же функция в зависимости от того где и что надо.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635644
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
israelshamir,

Дальше сам допилишь:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
with r(
       parent_folder_name,
       folder_name,
       subfolders
      ) as (
             select  null,
                     t.j.name,
                     t.j.subfolders
               from  tbl t
            union all
             select  r.folder_name,
                     jt.folder_name,
                     jt.subfolders
               from  r r,
                     json_table(
                                r.subfolders,'$[*]'
                                columns(
                                        folder_name varchar2(15) path '$.name',
                                        subfolders varchar2(4000) format json path '$.subfolders'
                                       )
                               ) jt
               where r.subfolders != '[]'
           )
select  parent_folder_name,
        folder_name
  from  r
/

PARENT_FOLDER_NAME   FOLDER_NAME
-------------------- ---------------
                     root_folder
root_folder          folder1
root_folder          folder2
root_folder          folder3
folder1              folder1_1
folder1              folder1_2
folder1_2            folder1_2_1

7 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635651
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правда тут и выяснятся что JSON_TABLE в Oracle заточен на статику и в отличие от XMLTABLE не дает вытащить ничего длиннее VARCHAR2(4000), т.е. если есть "sub-JSON" пoльзуйся статическим NESTED PATH. Так-что если subfolders > 4000 байт то труба
и придется парсить вручную.

SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635702
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
israelshamir,

не надо мучиться с json - проще конвертнуть в xml и разобрать:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select
   parent,name
from xmltable('//name'
              passing apex_json.to_xmltype(:твой_json)
              columns
                parent varchar2(100) path './../../../name'
               ,name  varchar2(100) path '.'
             ) x;


пример
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
select
   parent,name
from xmltable('//name'
              passing apex_json.to_xmltype(
--начало JSON:
q'#
{
    "name": "root_folder",
    "subfolders": [
        {
            "name": "folder1",
            "subfolders": [
                {
                    "name": "folder1_1",
                    "subfolders": []
                },
                {
                    "name": "folder1_2",
                    "subfolders": [
                        {
                            "name": "folder1_2_1",
                            "subfolders": []
                        }
                    ]
                }
            ]
        },
        {
            "name": "folder2",
            "subfolders": []
        },
        {
            "name": "folder3",
            "subfolders": []
        }
    ]
}
#' -- конец JSON
              )
              columns
                parent varchar2(100) path './../../../name'
               ,name  varchar2(100) path '.'
             ) x;

PARENT                         NAME
------------------------------ ------------------------------
                               root_folder
root_folder                    folder1
folder1                        folder1_1
folder1                        folder1_2
folder1_2                      folder1_2_1
root_folder                    folder2
root_folder                    folder3

7 rows selected.

...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635763
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
Код: plsql
1.
apex_json

Ага.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635783
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Спасибо за помощь!
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39635785
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender,


Спасибо за помощь!
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636018
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

А что APEX уже лицензии не требует?

SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636035
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SY,

А что раньше требовало?
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636054
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderА что раньше требовало?

APEX не пользую. Был уверен что требует. Сейчас посмотрел - требует только если нет лицензионной базы.

SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636118
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY Сейчас посмотрел - требует только если нет лицензионной базы.
Ээээ... "покупая у нас APEX за деньги вы признаетесь, что используете нелицензионную БД"?
:)
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636418
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender,

Перерыл документацию, так и не понял, как работает xquery в случае с parent. './../../../name' - 4 уровня.
Я добавил еще несколько уровней в JSON из примера, твой запрос парсит и их, хотя я ожидал увидеть NULL'ы
Объясни, пожалуйста, как это работает, почему именно 4 уровня('./../../../name') указал?
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636421
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
israelshamirxtender,

Перерыл документацию, так и не понял, как работает xquery в случае с parent. './../../../name' - 4 уровня.


На 3 уровня вверх а не на 4. Чтобы это понять нужно посмотреть сгенерированный XML. Там будет что-то типа:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <name>root_folder</name>
   <subfolders>
      <element>
         <name>folder1</name>
         <subfolders>
            <element>
               <name>folder1_1</name>
               <subfolders />
            </element>
...



T.e. если мы от текущего name (например folder1_1) поднимемся на './../../../name' то попадем на name папашки (folder1).

SY.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39636513
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

SYНа 3 уровня вверх а не на 4.


Здесь все прояснилось)
Большое спасибо, SY!
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39637119
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
WITH cte AS ( 
      select
         parent,name,ROWNUM rn
      from xmltable('//name'
                    passing apex_json.to_xmltype(
      --начало JSON:
      q'#
      {
          "name": "root_folder",
          "subfolders": [
              {
                  "name": "folder1",
                  "subfolders": [
                      {
                          "name": "folder1_1",
                          "subfolders": []
                      },
                      {
                          "name": "folder1_2",
                          "subfolders": [
                              {
                                  "name": "folder1_2_1",
                                  "subfolders": []
                              }
                          ]
                      }
                  ]
              },
              {
                  "name": "folder2",
                  "subfolders": []
              },
              {
                  "name": "folder3",
                  "subfolders": []
              }
          ]
      }
      #' -- конец JSON
                    )
                    columns
                      parent varchar2(100) path './../../../name'
                     ,name  varchar2(100) path '.'
                   ) x),
    cte2 AS (
     SELECT c1.name, c1.rn id_dir, c2.rn id_parent_dir
       FROM cte c1
  LEFT JOIN cte c2      
         ON c1.parent = c2.name)
    SELECT c2.*
          ,sys_connect_by_path(c2.name, '\') fullpath
      FROM cte2 c2
     START WITH c2.id_parent_dir IS NULL
   CONNECT BY PRIOR c2.id_dir = c2.id_parent_dir



Хочу получить fullpath.
Поскольку xquery почти не знаю и в данный момент нет времени на изучение, решил использовать sys_connect_by_path.
Не понимаю почему в результате в id_parent_dir null, fullpath'ы не построены.
Но, если данные из cte2 залить в таблицу и уже на ее основе строить запрос, отрабатывает правильно.

Грешу на:
1)Не знаю нюансов xmltable
2)Трансформации
3)Баг(?)

Прошу помощи, ткните носом в доку, блог и т.д. или объясните, пожалуйста.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39637416
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
israelshamir3)Баг(?)да, но вообще не нужно их смешивать, достаточно xmltable:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
WITH 
 xmldata as (
      select
        apex_json.to_xmltype(
      --начало JSON:
      q'#
      {
          "name": "root_folder",
          "subfolders": [
              {
                  "name": "folder1",
                  "subfolders": [
                      {
                          "name": "folder1_1",
                          "subfolders": []
                      },
                      {
                          "name": "folder1_2",
                          "subfolders": [
                              {
                                  "name": "folder1_2_1",
                                  "subfolders": []
                              }
                          ]
                      }
                  ]
              },
              {
                  "name": "folder2",
                  "subfolders": []
              },
              {
                  "name": "folder3",
                  "subfolders": []
              }
          ]
      }
      #' -- конец JSON
      ) as xmldata
      from dual
 )
,cte AS (
      select--+ no_merge 
         id_dir, 
         parent, 
         name,
         path,
         xpath,
         nvl2(ltrim(xpath_parent,'/'),ltrim(xpath_parent,'/')||'/name','') xpath_parent
      from xmldata,
           xmltable('//name'
                    passing xmldata.xmldata
                    columns
                      id_dir for ordinality
                     ,parent varchar2(100) path './../../../name'
                     ,name  varchar2(100) path '.'
                     ,path varchar2(100) path 'string-join(ancestor-or-self::*/name, "/")'
                     ,xpath varchar2(100) path 'string-join(ancestor-or-self::*/name(.), "/")'
                     ,xpath_parent varchar2(100) path 'string-join(ancestor-or-self::*/name(./../../..), "/")'
                   ) x
 )
select
 c.*
from cte c


ps. я специально убрал этот длиннющий json и трансформацию в xmldata, чтобы не мешал читать параметры xmltable. Если хочешь можешь вернуть...
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39637504
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xtender,

Какая красота...
Огромное спасибо за помощь.
Позже изучу SQL/XML, SQL/JSON, xquery.
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39661358
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
коллеги, apex_json как ставится? с админов требовать?
у нас оракл честно купленный
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39661419
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пусть ставят апекс, он с ним и придёт
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39661423
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
...
Рейтинг: 0 / 0
распарсить json(глубина не известна), залить в таблицу
    #39661484
israelshamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / распарсить json(глубина не известна), залить в таблицу
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]