Unnest JSON Array

2022. 6. 7.·Oracle/JSON

개요

PostgreSQL의 UNNEST 함수는 배열 값을 로우 형식으로 반환합니다. 다수의 배열 값을 입력하면 같은 위치의 배열 값이 하나의 로우로 반환됩니다. Oracle Database는 JSON 배열과 PL/SQL 함수로 유사한 기능을 구현할 수 있습니다.

 

PostgreSQL

테스트를 위해 아래와 같이 테이블을 생성하겠습니다.

-- 1
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INTEGER[], c2 TEXT[]);

INSERT INTO t1 VALUES ('{1,2,3}', '{"A","B"}');
-- INSERT INTO t1 VALUES (ARRAY[1,2,3], ARRAY['A','B']);
COMMIT;

 

UNNEST 함수는 아래와 같이 동작합니다.

-- 2-1
SELECT UNNEST (c1) AS c1, UNNEST (c2) AS c2 FROM t1;

 c1 | c2
----+----
  1 | A
  2 | B
  3 |

(3 rows)

-- 2-2
SELECT b.c1, b.c2 FROM t1 a, UNNEST (a.c1, a.c2) b (c1, c2);

 c1 | c2
----+----
  1 | A
  2 | B
  3 |

(3 rows)

 

Oracle Database

테스트를 위해 아래와 같이 테이블을 생성하겠습니다.

-- 3
DROP TABLE t1 PURGE;
CREATE TABLE t1 (c1 VARCHAR2(4000), c2 VARCHAR2(4000));

INSERT INTO t1 VALUES ('[1,2,3]', '["A","B"]');
COMMIT;

 

JSON_TABLE 표현식은 단일 JSON 배열을 로우 형식으로 반환할 수 있지만 다수의 JSON 배열을 처리할 수 없습니다.

-- 4-1
SELECT b.c1
  FROM t1 a
     , JSON_TABLE (a.c1, '$[*]' COLUMNS c1 NUMBER PATH '$[0]') b;

C1
--
 1
 2
 3

3 행이 선택되었습니다.

-- 4-2
SELECT b.c1, c.c2
  FROM t1 a
     , JSON_TABLE (a.c1, '$[*]' COLUMNS c1 NUMBER         PATH '$[0]') b
     , JSON_TABLE (a.c2, '$[*]' COLUMNS c2 VARCHAR2(4000) PATH '$[0]') c;

C1 C2
-- --
 1 A
 1 B
 2 A
 2 B
 3 A
 3 B

6 행이 선택되었습니다.

 

아래 fnc_json_array_unnest 함수는 입력된 JSON 배열을 UNNEST 가능한 JSON 배열로 변환합니다.

-- 5
CREATE OR REPLACE FUNCTION fnc_json_array_unnest (i_source IN VARCHAR2)
    RETURN VARCHAR2
IS
    v_max_size NUMBER       := 0;
    v_source   JSON_ARRAY_T := JSON_ARRAY_T (i_source);
    v_buffer   JSON_ARRAY_T := JSON_ARRAY_T ();
    v_result   JSON_ARRAY_T := JSON_ARRAY_T ();
BEGIN
    FOR i IN 0 .. v_source.GET_SIZE - 1 LOOP
        v_max_size := GREATEST (v_max_size, JSON_ARRAY_T (v_source.GET_STRING (i)).GET_SIZE);
    END LOOP;

    FOR i IN 0 .. v_max_size - 1 LOOP
        FOR j IN 0 .. v_source.GET_SIZE - 1 LOOP
            v_buffer.APPEND (JSON_ARRAY_T (v_source.GET_STRING (j)).GET_STRING (i));
        END LOOP;
        v_result.APPEND (v_buffer);
        v_buffer := JSON_ARRAY_T ();
    END LOOP;

    RETURN v_result.STRINGIFY;
END;
/

 

아래는 fnc_json_array_unnest 함수를 사용한 결과입니다.

-- 6
SELECT c1
     , c2
     , json_array (c1, c2) AS json_array
     , fnc_json_array_unnest (json_array (c1, c2)) AS json_array_unnest
  FROM t1;

C1      C2        JSON_ARRAY                  JSON_ARRAY_UNNEST
------- --------- --------------------------- --------------------------------
[1,2,3] ["A","B"] ["[1,2,3]","[\"A\",\"B\"]"] [["1","A"],["2","B"],["3",null]]

1개의 행이 선택되었습니다.

 

fnc_json_array_unnest 함수와 JSON_TABLE 표현식을 사용하면 PostgreSQL의 UNNEST 함수와 동일한 결과를 얻을 수 있습니다.

-- 7
SELECT b.c1, b.c2
  FROM t1 a
     , JSON_TABLE (fnc_json_array_unnest (JSON_ARRAY (a.c1, a.c2))
                 , '$[*]' COLUMNS (
                       c1 NUMBER         PATH '$[0]'
                     , c2 VARCHAR2(4000) PATH '$[1]')) b;

C1 C2
-- --
 1 A
 2 B
 3

3 행이 선택되었습니다.
저작자표시 비영리 변경금지
'Oracle/JSON' 카테고리의 다른 글
  • JSON_TRANSFORM 함수 기능 개선
  • JSON PASSING 절 개선
  • CSV to JSON Array
  • JSON_EACH 함수
정희락
정희락
2007년부터 Oracle Database 성능 최적화에 주력해 왔으며, 현재 한국오라클 Engineered Systems Solution Engineering 팀에서 Solution Engineer로 근무하고 있습니다. 이 블로그는 개인적인 연구 목적으로 운영되며, Oracle 사의 공식 입장을 대변하지 않습니다.
  • 정희락
    TunA
    정희락
  • 전체
    오늘
    어제
    • 분류 전체보기 (194)
      • Oracle (166)
        • SQL (32)
        • PLSQL (10)
        • Performance (72)
        • Administration (36)
        • Installation (3)
        • Utilities (1)
        • JSON (8)
        • Vector (4)
      • Exadata (15)
      • SQL*Plus (2)
      • Linux (5)
      • Resources (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 도서

    • 불친절한 SQL 프로그래밍
    • 불친절한 PL/SQL 프로그래밍
  • 태그

    12c
    19c
    21c
    23ai
    case study
  • 공지사항

  • 최근 글

  • 최근 댓글

  • 인기 글

  • 링크

    • Connor McDonald
    • Frits Hoogland
    • Jonathan Lewis
    • Julian Dontcheff
    • Julian Dyke
    • Kun Sun
    • Maria Colgan
    • Martin Bach
    • Mike Dietrich
    • Tanel Poder
  • hELLO· Designed By정상우.v4.10.0
정희락
Unnest JSON Array
상단으로

티스토리툴바