powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Парсинг JSON средствами Oracle 12
12 сообщений из 12, страница 1 из 1
Парсинг JSON средствами Oracle 12
    #39190301
alteksa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго всем времени суток!

Дело в том, что была поставлена задача парсить курсы валют по разным банкам. Имея API с JSON, на которой собраны уже все курсы решили нативными средствами 12-го Oracle парсить эти курсы в таблицу или представление.

Подскажите пожалуйста, как лучше поступить в данной ситуации?
С PL/JSON ознакомились, хотелось бы использовать нативные средства.

Для начала был импортирован json в clob поле таблицы, назовём её тут RATES_JSON.

Вот отрывок используемого json-а
Код: 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.
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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
{
  "exim": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 20.04,
      "buy": 19.85
    },
    "EUR": {
      "sell": 22,
      "buy": 21.7
    },
    "RUB": {
      "sell": 0.285,
      "buy": 0.27
    },
    "RON": {
      "sell": 4.93,
      "buy": 4.6
    },
    "UAH": {
      "sell": 0.9,
      "buy": 0.4
    }
  },
  "maib": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 20.07,
      "buy": 19.9
    },
    "EUR": {
      "sell": 22.07,
      "buy": 21.83
    },
    "RUB": {
      "sell": 0.286,
      "buy": 0.274
    },
    "RON": {
      "sell": 4.96,
      "buy": 4.69
    },
    "UAH": {
      "sell": 0.85,
      "buy": 0.55
    },
    "GBP": {
      "sell": 28.45,
      "buy": 27.75
    },
    "CHF": {
      "sell": 20.1,
      "buy": 19.4
    }
  },
  "mobi": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 20.07,
      "buy": 19.9
    },
    "EUR": {
      "sell": 22.07,
      "buy": 21.77
    },
    "RUB": {
      "sell": 0.285,
      "buy": 0.275
    }
  },
  "degh": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 19.9,
      "buy": 19.87
    },
    "EUR": {
      "sell": 21.82,
      "buy": 21.78
    },
    "RUB": {
      "sell": 0.276,
      "buy": 0.274
    },
    "RON": {
      "sell": 4.89,
      "buy": 4.84
    },
    "UAH": {
      "sell": 0.77,
      "buy": 0.74
    },
    "GBP": {
      "sell": 27.9,
      "buy": 27.8
    },
    "CHF": {
      "sell": 20.2,
      "buy": 20.05
    }
  },
  "come": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 19.94,
      "buy": 19.9
    },
    "EUR": {
      "sell": 21.88,
      "buy": 21.8
    },
    "RUB": {
      "sell": 0.28,
      "buy": 0.27
    },
    "UAH": {
      "sell": 0.9,
      "buy": 0.3
    }
  },
  "fin": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 20,
      "buy": 19.91
    },
    "EUR": {
      "sell": 21.98,
      "buy": 21.83
    },
    "RUB": {
      "sell": 0.285,
      "buy": 0.274
    },
    "RON": {
      "sell": 4.9,
      "buy": 4.72
    },
    "UAH": {
      "sell": 0.77,
      "buy": 0.67
    },
    "GBP": {
      "sell": 28.2,
      "buy": 27.1
    }
  },
  "vb": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 20.09,
      "buy": 19.87
    },
    "EUR": {
      "sell": 22.07,
      "buy": 21.7
    },
    "RUB": {
      "sell": 0.287,
      "buy": 0.27
    },
    "RON": {
      "sell": 4.9,
      "buy": 4.5
    },
    "UAH": {
      "sell": 0.9,
      "buy": 0.6
    },
    "GBP": {
      "sell": 28.5,
      "buy": 27.3
    },
    "CHF": {
      "sell": 20.7,
      "buy": 19.8
    }
  },
  "baltigara": {
    "MDL": {
      "sell": 1,
      "buy": 1
    },
    "USD": {
      "sell": 19.94,
      "buy": 19.9
    },
    "EUR": {
      "sell": 21.86,
      "buy": 21.8
    },
    "RUB": {
      "sell": 0.28,
      "buy": 0.272
    },
    "RON": {
      "sell": 4.9,
      "buy": 4.8
    },
    "UAH": {
      "sell": 0.77,
      "buy": 0.73
    },
    "GBP": {
      "sell": 28.7,
      "buy": 27.7
    },
    "CHF": {
      "sell": 20.45,
      "buy": 19.1
    }
  }
}



Как парсить текст по значениям используя JSON_TABLE чтобы создавать поля по каждому банку - понятно, но хотелось бы разбить текст по полям "банки"-"валюта"-"покупка"-"продажа"?

В общем, главный вопрос - как создать поле с содержимым только родительской категории без дочерних данных?

Заранее благодарен!
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39190306
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alteksaКак парсить текст по значениям используя JSON_TABLE чтобы создавать поля по каждому банку - понятноСвою понятливость принято подтверждать кодом.
alteksaкак создать поле с содержимым только родительской категории без дочерних данных??!! http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39190338
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alteksaхотелось бы использовать нативные средстваО каких именно нативных средствах речь?
Код: plsql
1.
2.
create table t (j clob, constraint check_json check (j is json))
insert ...


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SQL> select
  2     json_value(j,'$.exim.USD.sell') x1,
  3     json_value(j,'$.*[0].USD.sell') x1,
  4     --..
  5     t.j.exim.USD.sell x2
  6  from t t;

X1                   X1                   X2
-------------------- -------------------- --------------------
20.04                20.04                20.04

json_value позволяет получать значения без указания конкретного банка.
Второй вариант преобразуется в json_query ( 18693271 ) и не дает такой возможности.
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39190415
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alteksa,
Что-то это не выглядит как нормальный json.
Теперь для того чтобы получить данные, нужно хардкодить PATHes. Для того чтобы преобразовать в реляционную модель нужен unpivot.
Код: 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.
create table parsed_json as  SELECT * FROM source_json sj, 
  json_table(sj.rates_json, '$'
         COLUMNS ("exim_usd_sell" VARCHAR2(10)  PATH '$.exim.USD.sell',
                  "exim_usd_buy" VARCHAR2(10)  PATH '$.exim.USD.buy',
                           
                  "exim_rub_sell" VARCHAR2(10)  PATH '$.exim.RUB.sell',
                  "exim_rub_buy" VARCHAR2(10) PATH '$.exim.RUB.buy'
                  -- И так далее 
                          )) jt
                          select * from parsed_json


with json_interim as (
SELECT 
* FROM parsed_json
unpivot
(
  rate
    for bank_curr_type in ("EXIM_USD_SELL","EXIM_USD_BUY","EXIM_RUB_SELL","EXIM_RUB_BUY")
)
order by bank_curr_type
)
SELECT  regexp_substr(bank_curr_type,'[^_]+', 1, 1) bank,
 regexp_substr(bank_curr_type,'[^_]+', 1, 2) currency,
 regexp_substr(bank_curr_type,'[^_]+', 1, 3) type, 
 rate
 FROM json_interim

BANK	CURRENCY	TYPE	RATE
EXIM	RUB	BUY	0.27
EXIM	RUB	SELL	0.285
EXIM	USD	BUY	19.85
EXIM	USD	SELL	20.04



А Теперь можно сравнить с json v2 :

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
{
	"Bankdata": [{
		"Bank": "exim",
		"Currency": "USD",
		"Sell": 20.04,
		"Buy": 19.85
	}, {
		"Bank": "exim",
		"Currency": "MDL",
		"Sell": 1,
		"Buy": 1
	}, {
		"Bank": "exim",
		"Currency": "RUB",
		"Sell": 0.285,
		"Buy": 0.27
	}]
}
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39191708
Uchastneg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а чем PL/JSON не устроил?
просто любопытно.
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39191717
Деев И.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного offtop, но только сегодня на тестовой базе (Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production, Solaris Operating System (x86-64)) пробовал и json_table и json_value.

Оказалось, json_table нельзя использовать в двух параллельно работающих сессиях.
Попробуйте в цикле запустить парсинг простейшего json через json_table и посмотрите, что получится. У меня результат был таким:
https://gyazo.com/75b8a1285e8ba41d6c1a03e46e502e17

Кроме того, даже если несколько полей вытаскивать через json_value ( у меня в примере было 4 поля) - получается раза в полтора быстрее, чем через json_table. Наверное, будет зависеть от кол-ва полей.

На SE2 вторая сессия просто отваливалась.

Баги-патчи не успел еще посмотреть.
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39191724
alteksa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicalteksaКак парсить текст по значениям используя JSON_TABLE чтобы создавать поля по каждому банку - понятноСвою понятливость принято подтверждать кодом.


Спасибо Ora601! "Свою понятливость" впредь буду подтверждать кодом, сейчас не вижу смысла, так как Ora601 написал то, что я имел ввиду. Правильнее было бы написать хардкодить до цифровых значений банк.валюта.тип_операции по примеру:
Код: javascript
1.
PATH '$.exim.USD.sell'
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39191725
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Деев И.Попробуйте в цикле запустить парсинг простейшего json через json_table и посмотрите, что получится.Попробуй предъявить test-case и, может быть, посмотрим.
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39191730
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Деев И.,

на той же версии полет нормальный...
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39192074
alteksa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elicalteksaкак создать поле с содержимым только родительской категории без дочерних данных??!! http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM

Используя FORMAT JSON PATH получаются отрывки JSON-а по банкам, к примеру банк MAIB:
Код: javascript
1.
{"MDL":{"sell":1,"buy":1},"USD":{"sell":20.07,"buy":19.9},"EUR":{"sell":22.07,"buy":21.83},"RUB":{"sell":0.286,"buy":0.274},"RON":{"sell":4.96,"buy":4.69},"UAH":{"sell":0.85,"buy":0.55},"GBP":{"sell":28.45,"buy":27.75},"CHF":{"sell":20.1,"buy":19.4}}



А хотелось бы сразу получать в таблицу root-категории, по типу:
bank_column---currency ...
EXIM--------------MDL ...
EXIM--------------USD ...
EXIM--------------EUR ...
EXIM--------------RUB ...
MAIB .... ...
...

Uchastnegа чем PL/JSON не устроил? просто любопытно.
Не то, чтобы не устроил - не хотелось бы тащить несколько сторонних пакетов на схему - пока есть необходимость только парсить курсы по валютам.
Наверное менталитет сказывается - когда нужен какой-то инструмент, то пробуем его найти у себя дома, если не находим ничего полезного дома, то идём к соседу. Также и тут, видимо придётся сделать на скорую руку свой инструмент, либо идти к соседу за pl/json или чем-то другим :)
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39193627
alteksa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотел выразить благодарность всем откликнувшимся!
Задача разрешилась следующим образом - экспериментируя с изначальным json-ом(представлен в первом посте), решили обратиться к ребятам которые делятся своей API и предоставляют JSON.
Ответив для чего нам нужна их API, они предоставили URL с токеном на котором есть нормально структурированный JSON(подробности под катом).
Кусок нового JSON-а
Код: 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.
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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
{
  "date": "2016-03-16",
  "currencies": [
    {
      "num_code": "111",
      "char_code": "USD",
      "nominal": "1",
      "name_ru": "Доллар США",
      "name_en": "US Dollar"
    },
    {
      "num_code": "112",
      "char_code": "EUR",
      "nominal": "1",
      "name_ru": "Евро",
      "name_en": "Euro"
    },
    {
      "num_code": "113",
      "char_code": "RUB",
      "nominal": "1",
      "name_ru": "Российский рубль",
      "name_en": "Russian Ruble"
    }
  ],
  "valcurs": [
    {
      "date": "2016-03-16",
      "banks": [
        {
          "ID": "exim",
          "name": "EXIMBANK-Gruppo Veneto Banca S.A.",
          "name_short": "Eximbank",
          "type": "BANK",
          "updated": "2016-03-16",
          "valute": [
            {
              "char_code": "USD",
              "nominal": "1",
              "sell": 19.95,
              "buy": 19.77,
              "value": 0
            },
            {
              "char_code": "EUR",
              "nominal": "1",
              "sell": 22.14,
              "buy": 21.89,
              "value": 0
            },
            {
              "char_code": "RUB",
              "nominal": "1",
              "sell": 0.285,
              "buy": 0.269,
              "value": 0
            }
          ]
        },
        {
          "ID": "ecb",
          "name": "B.C. EuroCreditBank S.A.",
          "name_short": "EuroCreditBank",
          "type": "BANK",
          "updated": "2016-03-16",
          "valute": [
            {
              "char_code": "USD",
              "nominal": "1",
              "sell": 19.9,
              "buy": 19.8,
              "value": 0
            },
            {
              "char_code": "EUR",
              "nominal": "1",
              "sell": 22.12,
              "buy": 21.92,
              "value": 0
            },
            {
              "char_code": "RUB",
              "nominal": "1",
              "sell": 0.282,
              "buy": 0.272,
              "value": 0
            }
          ]
        }
      ]
    }
  ]
}




А с этим текстом уже взятки гладки:

Получаем банки:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select jt.* 
  from t_rates_json sj, json_table
  (
    sj.data, '$.valcurs[0].banks[*]' columns
    (
                 "name" varchar2(100) path '$.ID',
                 "name_full" varchar2(100) path '$.name',
                 "name_short" varchar2(100) path '$.name_short'    
    )
  ) jt 



Потом курсы:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
select to_date(jt.rate_date, 'yyyy-mm-dd') rate_date
      , (select b.id from t_banks b where b.name = jt.bank_name) bank
      , jt.char_code curr
      , decode(jt.value, '0', jt.sell, jt.value) sell
      , decode(jt.value, '0', jt.buy,  jt.value) buy
    from t_rates_json sj, json_table
    (
      sj.data, '$.valcurs[0]' columns
      (
        "rate_date"  varchar2(100) path '$.date',
        nested path '$.banks[*]' columns
        (
          "bank_name" varchar2(100) path '$.ID',     
          nested path '$.valute[*]' columns
          (
            "char_code" varchar2(100) path '$.char_code',
            "sell" varchar2(100) path '$.sell',
            "buy" varchar2(100) path '$.buy',
            "value" varchar2(100) path '$.value'
          )
        )
      )
    ) jt



Всем спасибо!
...
Рейтинг: 0 / 0
Парсинг JSON средствами Oracle 12
    #39327644
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>>Оказалось, json_table нельзя использовать в двух параллельно работающих сессиях.

немного некрофилии. Ага, мы тоже на это наткнулись. Лечится установкой 2 патчей по джейсону от оракла.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Парсинг JSON средствами Oracle 12
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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