2016-09-15 2 views
0

Я пытаюсь найти простой способ генерации SQL-запроса как JSON, но я подхожу. Это запрос:Уменьшить Oracle Query, чтобы вернуть только владельца

SELECT DISTINCT owner 
FROM dba_segments 
WHERE owner NOT IN ('SYS', 'SYSTEM', 'EXFSYS', 'DBSNMP', 'SQLTXPLAIN', 'XDB', 'WMSYS', 'PERFSTAT', 'OUTLN'); 

То, что я хочу, чтобы этот экран JSON похож на это:

{ 
    "data": [{ 
     "{#Owner}": "ABC123Test" 
    }, { 
     "{#Owner}": "Accounting" 
    }, { 
     "{#Owner}": "Treasury" 
    }, { 
     "{#Owner}": "Production1" 
    }] 
} 

В SQL Server я бы просто использовать XML PATH и сделать что-то вроде этого -

SELECT '{"data":[' + (SELECT CAST(STUFF((SELECT ',' + '{"{#Owner}":"' + DISTINCT[owner] + '"}' 
FROM dba_segments 
where owner not in ('SYS', 'SYSTEM', 'EXFSYS', 'DBSNMP', 'SQLTXPLAIN', 'XDB', 'WMSYS', 'PERFSTAT', 'OUTLN') FOR XML PATH('')), 1, 1, '') AS VARCHAR(MAX))) + ']}' as 'XML_F52E2B61-18A1-11d1-B105-00805F49916B' 
+0

Обратите внимание, что все имена макросов/переменных должны быть заглавными, например {#OWNER}. – Richlv

ответ

1

Что-то вроде этого:

SELECT '{ "data": [{'||listagg('"{#owner}":"'||owner||'"}', ',') within group (order by owner)||'}]}' as json 
FROM (
    select distinct owner 
    from dba_segments 
    WHERE owner NOT IN ('SYS', 'SYSTEM', 'EXFSYS', 'DBSNMP', 'SQLTXPLAIN', 'XDB', 'WMSYS', 'PERFSTAT', 'OUTLN', 'APEX_040200') 
) t; 

(Не уверен, что если бы я получил вложенности всех { и [ справа)

+0

Я просто запустил запрос и получил Следующее - '' {"DATA": [{'|| LISTAGG (' "{# OWNER}": "'|| OWNER ||'"} ',', ') WITHINGROUP (ORDERBYOWNER) ||'}]} '' – whoisearth

+0

@whoisearth: ну, это имя по умолчанию, которое Oracle назначает выражению (я изменил запрос на предоставление псевдонима столбца). Он должен возвращать одну строку с данными JSON - если в вашей системе нет пользователей, которые бы соответствовали предложению 'where' в производной таблице. Что означает 'select count (отдельный владелец) из dba_segments, где владелец не в (...)' return? –

+0

Я собираюсь назвать свое невежество оракулом. Я запустил ваше обновление, и он просто показывает 'JSON', но что вы говорите, если я должен запустить его в sql-разработчике, он фактически отображает данные? – whoisearth

0

Если вам не нужен действительно большой проект на ваших руках, вы действительно не хотите откатывать свой собственный парсер/писатель JSON. Для многих проектов я использовал PLJSON, который представляет собой библиотеку пакетов, которые могут манипулировать/анализировать/писать JSON внутри PL/SQL. Я уверен, что есть и другие варианты, но это хорошо для меня.

EDIT:

Похоже, в 12с, Oracle поддерживает JSON. См. here для получения дополнительной информации.

+0

Поддержка JSON в Oracle 12 не поможет, поскольку она разрешает только _query_ JSON-документам, но не _generate_ их (например, как 'row_to_json()' или 'json_agg()' в Postgres) –

1

Использование 12.2.0.1.0 Это работает (Обратите внимание, я должен был использовать материализуйте предложение WITH, чтобы получить правильные результаты)

SQL> set lines 89 
SQL> with DBA_SEGMENT_OWNERS 
    2 as 
    3 (
    4 select /*+ MATERIALIZE */ DISTINCT OWNER 
    5  from dba_segments 
    6  where owner NOT IN ('SYS', 'SYSTEM', 'EXFSYS', 'DBSNMP', 'SQLTXPLAIN', 'XDB', 'WMSYS', 'PERFSTAT') 
    7 ) 
    8 select JSON_OBJECT('data' is JSON_ARRAYAGG(JSON_OBJECT('{#Owner}' is OWNER))) 
    9 from DBA_SEGMENT_OWNERS 
10/
{"data":[{"{#Owner}":"MDSYS"},{"{#Owner}":"VPDTEST"},{"{#Owner}":"CTXSYS"},{"{#Owner}":"H 
R"},{"{#Owner}":"DVSYS"},{"{#Owner}":"AUDSYS"},{"{#Owner}":"SCOTT"},{"{#Owner}":"VPDOWNER 
"},{"{#Owner}":"GSMADMIN_INTERNAL"},{"{#Owner}":"OJVMSYS"},{"{#Owner}":"ORDSYS"},{"{#Owne 
r}":"ORDS_METADATA"},{"{#Owner}":"ORDDATA"},{"{#Owner}":"XDBEXT"},{"{#Owner}":"LBACSYS"}, 
{"{#Owner}":"XFILES"}]} 


SQL>