18.1 버전에 다형성 테이블 함수(Polymorphic Table Function, PTF) 기능이 추가되었다. PTF는 새로운 유형의 테이블 함수로 입력된 인수에 의해 반환 형식이 결정된다. 간단한 예제를 살펴보자. 1
테스트를 위해 아래와 같이 패키지를 생성하자. fnc_flat 함수는 테이블과 구분자를 입력받아 플랫 파일 형식의 결과를 반환한다.
-- 1-1 CREATE OR REPLACE PACKAGE pkg_flat IS FUNCTION fnc_flat ( i_tab IN TABLE , i_del IN VARCHAR2 DEFAULT ',' ) RETURN TABLE PIPELINED ROW POLYMORPHIC USING pkg_flat; FUNCTION describe ( i_tab IN OUT DBMS_TF.TABLE_T , i_del IN VARCHAR2 DEFAULT ',' ) RETURN DBMS_TF.DESCRIBE_T; PROCEDURE fetch_rows ( i_del IN VARCHAR2 DEFAULT ',' ); END pkg_flat; / -- 1-2 CREATE OR REPLACE PACKAGE BODY pkg_flat IS FUNCTION describe ( i_tab IN OUT DBMS_TF.TABLE_T , i_del IN VARCHAR2 DEFAULT ',' ) RETURN DBMS_TF.DESCRIBE_T IS l_col_new DBMS_TF.COLUMNS_NEW_T; BEGIN FOR i IN 1 .. i_tab.COLUMN.COUNT LOOP CONTINUE WHEN NOT DBMS_TF.SUPPORTED_TYPE (i_tab.COLUMN(i).DESCRIPTION.TYPE); i_tab.COLUMN(i).PASS_THROUGH := FALSE; i_tab.COLUMN(i).FOR_READ := TRUE; END LOOP; l_col_new(1) := DBMS_TF.COLUMN_METADATA_T (name => 'COLUNM_VALUE', type => DBMS_TF.TYPE_VARCHAR2); RETURN DBMS_TF.DESCRIBE_T (new_columns => l_col_new); END describe; PROCEDURE fetch_rows ( i_del IN VARCHAR2 DEFAULT ',' ) IS l_row_set DBMS_TF.ROW_SET_T; l_row_cnt PLS_INTEGER; l_col_cnt PLS_INTEGER; l_tab_col DBMS_TF.TAB_VARCHAR2_T; BEGIN DBMS_TF.GET_ROW_SET (l_row_set, l_row_cnt, l_col_cnt); FOR r IN 1 .. l_row_cnt LOOP l_tab_col(r) := NULL; FOR c IN 1 .. l_col_cnt LOOP l_tab_col(r) := l_tab_col(r) || i_del || TRIM ('"' FROM DBMS_TF.COL_TO_CHAR (l_row_set(c), r)); END LOOP; l_tab_col(r) := LTRIM (l_tab_col(r), i_del); END LOOP; DBMS_TF.PUT_COL (1, l_tab_col); END fetch_rows; END pkg_flat; /
아래 쿼리는 PTF에 dept 테이블을 인수로 입력했다.
-- 2 SELECT * FROM pkg_flat.fnc_flat (dept); COLUNM_VALUE ---------------------- 10,ACCOUNTING,NEW YORK 20,RESEARCH,DALLAS 30,SALES,CHICAGO 40,OPERATIONS,BOSTON 4 행이 선택되었습니다. ---------------------------------------------------------------------------- | Id | Operation | Name | Starts | A-Rows | Buffers | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 0 | 0 | 0 | | 1 | POLYMORPHIC TABLE FUNCTION | FNC_FLAT | 1 | 4 | 85 | -- ! | 2 | TABLE ACCESS FULL | DEPT | 1 | 4 | 6 | ----------------------------------------------------------------------------
WITH 절을 사용하면 PTF에 서브 쿼리를 입력할 수 있다. 실행 계획 1번에서 144개의 블록 I/O가 발생한 것을 확인할 수 있다. 리컬시브 콜에 의한 블록 I/O로 좀 더 테스트가 필요할 것 같다.
-- 3 WITH w1 AS (SELECT empno, ename, hiredate, sal FROM emp WHERE deptno = 10) SELECT * FROM pkg_flat.fnc_flat (w1); COLUNM_VALUE ------------------------------------ 7782,CLARK,1981-06-09 00:00:00,2450 7839,KING,1981-11-17 00:00:00,5000 7934,MILLER,1982-01-23 00:00:00,1300 3 행이 선택되었습니다. ------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | A-Rows | Buffers | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 0 | 0 | 0 | | 1 | POLYMORPHIC TABLE FUNCTION | FNC_FLAT | 1 | 3 | 146 | -- ! | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| EMP | 1 | 3 | 2 | | 3 | INDEX RANGE SCAN | EMP_X1 | 1 | 3 | 1 | -------------------------------------------------------------------------------------
- ANSI SQL 2016에 포함된 기능이다. [본문으로]
'Oracle > PL/SQL' 카테고리의 다른 글
ETL 유틸리티 패키지 (1) | 2020.02.13 |
---|---|
단위 변환 함수 (0) | 2018.12.31 |
에러 메시지 조회 함수 (0) | 2018.12.24 |
런타임 실행 계획 조회 함수 (0) | 2018.12.12 |
RAW 변환 함수 (0) | 2018.11.13 |