문서유형ㅣ기술정보
분야ㅣ마이그레이션
적용제품버전ㅣ7FS02, 7FS02PS
문서번호ㅣTMITI043
개요
Tibero에서 제공하는 XMLTYPE은 XML 데이터를 처리하기 위한 데이터 타입으로, 내부적으로 CLOB 기반과 OBJECT 기반 두 가지 방식으로 제공합니다.
DB 이관 시, AS-IS 환경과 TO-BE 환경에서 XMLTYPE 데이터 타입을 동일하게 유지하려면 CLOB 기반 XMLTYPE을 OBJECT 기반 XMLTYPE으로 변환해야 합니다. O사에서는 XMLTYPE이 기본적으로 OBJECT 타입으로 저장되며, Tibero로 이관 시 이를 맞추기 위한 변환 작업이 필요합니다.
방법
XMLTYPE 확인 방법
$ cd $TB_HOME/scripts/pkg
$ tbsql sys/tibero
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> @xmltype_install_checker.sql
XMLTYPE OID(00000000000000000000000000000001) IS VALID
===XMLTYPE(CLOB) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU INSTALL XMLTYPE(OBJECT)
YOU CAN INSTALL XMLTYPE(OBJECT)!!
PSM completed.XMLTYPE OBJECT TYPE으로 변경 방법
$ cd $TB_HOME/scripts/pkg
$ tbsql sys/tibero
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> @install_xmltype.sql
Type 'XMLTYPE' created.
Type 'XMLSEQUENCETYPE' created.
Package 'STANDARD_EXTENSION_XML' created.
System altered.
Type 'SQLPROF_ATTR' created.
Synonym 'SQLPROF_ATTR' created.
Granted.
Package 'DBMS_SQLTUNE' created.
Synonym 'DBMS_SQLTUNE' created.
...
Package 'SYS.DBMS_METADATA' altered.
Package 'SYS.DBMS_XMLGEN' altered.
Package 'SYS.DBMS_XMLPARSER' altered.
Package 'SYS.DBMS_XSLPROCESSOR' altered.
SQL>OBJECT TYPE으로 변경 확인
$ cd $TB_HOME/scripts/pkg
$ tbsql sys/tibero
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> @xmltype_install_checker.sql
===XMLTYPE(OBJECT) IS ALREADY INSTALLED===
===XMLTYPE(OBJECT) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU UNINSTALL XMLTYPE(OBJECT)
YOU CAN UNINSTALL XMLTYPE(OBJECT)!!
PSM completed.
XMLTYPE INTERFACE 변경 방법
XMLTYPE은 CLOB 형태와 OBJECT 형태가 있습니다. XMLTYPE CLOB형태는 CLOB과 동일한 방식으로 구현되어 있고, XMLTYPE OBJECT형태는 아래와 유사한 OBJECT TYPE 생성 DD을 통해 생성됩니다. XMLTYPE OBJECT형태는 OBJECT 안에 CLOB을 가진 형태고 해당 CLOB에 XMLTYPE이 저장되게 됩니다.
CREATE OR REPLACE TYPE XMLTYPE AS OBJECT(
Doc CLOB,
…
);
/ 최종적인 저장은 CLOB에 되는 것으로 보이므로 동일하게 보일 수 있지만, OBJECT TYPE으로 구현되어 있기 때문에 OBJECT의 특성을 가지고 있게 되어 TYPE 안에 멤버함수를 가지게 되고, OBJECT TYPE으로부터 멤버함수를 호출하는 방식을 사용할 수 있습니다.
따라서, XMLTYPE OBJECT Interface에 대해서 설명을 드리면 OBJECT의 특성을 가지고 있어서 TYPE으로부터 직접 멤버함수를 호출할 수 있는 방식입니다. ORACLE 또는 TIBERO에서 XMLTYPE을 OBJECT로 설치했을 경우, OBJECT Interface를 이용하여 XMLTYPE을 사용할 수 있습니다.
다음으로 XMLTYPE CLOB Interface에 대해서 설명 드리면, 기존 TIBERO의 경우 XMLTYPE을 CLOB으로 지원하였습니다. CLOB과 동일하다 보니 OBJECT 형태의 호출방식을 사용하지 못하기 때문에 STANDARD 함수 호출 방식으로 구현되어 있습니다. OBJECT Interface에서, XMLTYPE 멤버함수 또는 XMLTYPE subprogram (https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/t_xml.htm#BABBJDAH) 은 아래와 같이 호출되게 됩니다.
[SQL]
create table t(c1 xmltype);
Insert into t values (xmltype(‘<example/>’));
Select x.c1.getclobval() from t x;
Select x.c1.existsnode(‘/example’) from t x;
[PSM]
declare
x xmltype;
Begin
x := xmltype(‘<example/>’);
dbms_output.put_line(x.getclobval()):
end;
/
Table 1. OBJECT Interface 방식
즉, ‘.’ 을 통해서 XMLTYPE 내부의 subprogram을 호출하게 됩니다. 하지만, object interface가 아니고, XMLTYPE이 CLOB으로 구현되어 있는 상태에서 위처럼 호출하면 CLOB에 ‘.’ 을 통해서 XMLTYPE 내부의 subprogram을 호출하는 이상한 호출 방식이 되게 됩니다.
따라서, CLOB상태에서 저런 호출 방식을 쓸 수 없기 때문에, CLOB Interface는 STANDARD 함수 호출방식으로 Subprogram들이 호출되고, 첫 번째 인자로 XMLTYPE을 주는 방식입니다. 그러므로, OBJECT INTERFACE를 CLOB Interface로 바꾸면 아래처럼 바꿀 수 있습니다.
[SQL]
create table t(c1 xmltype);
Insert into t values (xmltype(‘<example/>’));
Select /*x.c1.getclobval()->*/ getclobval(x.c1) from t x;
Select /*x.c1.existsnode(‘/example’)->*/ existsnode(x.c1) from t x;
[PSM]
declare
x xmltype;
Begin
x := xmltype(‘<example/>’);
dbms_output.put_line(getclobval(x)):
end;
/
Table 2. CLOB Interface 방식
따라서, XMLTYPE OBJECT Interface -> XMLTYPE CLOB Interface 방법은
INSTANCE.FUNCTION(…) -> FUNCTION(INSTANCE, …) 식으로 바꾸면 됩니다.
예외 CASE1) 함수 이름이 다른 함수들
TRANSFORM와 EXTRACT 함수의 경우, 일반적인 STANDARD 함수 형태로 제공할 경우 동일한 함수와 충돌이 일어나서 유사한 함수명으로 변경하여 XMLTRANSFROM, EXTRACT_XML을 호출 해줘야 합니다.
[Object Interface] Declare x xmltype := ‘….’; xsl xmltype; := ‘….’; res xmltype; Begin res := x.transform(xsl); res := res.extract(‘/element1’); dbms_output.put_line(res.getstringval()); End; / | [Clob Interface] Declare x xmltype := ‘….’; xsl xmltype; := ‘….’; res xmltype; Begin res := xmltransform(x, xsl); res := extract_xml(res, ‘/element1’); dbms_output.put_line(res); End; / |
예외 CASE2) TABLE함수 사용 시 차이점
TABLE과 같이 사용될 경우, OBJECT TYPE은 value라는 함수를 이용하여 OBJECT의 value값만 출력하도록 하는 기능을 사용하는데 CLOB의 경우는 OBJECT가 아니므로 value함수를 쓰면 error가 나게 됩니다. 따라서, 일반적으로 primitive type column이 출력되는 case처럼 table함수의 결과를 출력하면 됩니다.
실제로는 TABLE함수 관점으로 보면 OBJECT TYPE이 value함수를 쓰는 예외 case가 되므로, XMLTYPE이 CLOB TYPE일 때는 아래 예제처럼 바꿔주시면 됩니다.
[Object Interface] Select extract(value(v), ‘/element’, ‘xmlns=http://www.loc.gov/MARC21/slim’ ).getstringval from xml_table a, table(xmlsequence ( extract(a.xml_column, ‘/f/a’, ‘xmlns=http://www.loc.gov/MARC21/slim’))) v; | [Clob Interface] Select extract(v.column_value, ‘/element’, ‘xmlns=http://www.loc.gov/MARC21/slim’) from xml_table a, table(xmlsequence( extract(a.xml_column, ‘/f/a’, ‘xmlns=http://www.loc.gov/MARC21/slim’))) v; |
예외 CASE3) PSM 안에서 SYS.XMLTYPE
이유는 아주 단순합니다. CLOB TYPE을 사용할 때, SYS.CLOB으로 사용하는 사람도 없고, 해당 기능이 동작하지도 않습니다. 따라서, XMLTYPE이 CLOB TYPE형태의 PRIMITIVE TYPE일 때는 SYS.XMLTYPE을 XMLTYPE으로 호출해줘야 합니다.
[Object Interface] create or replace function func3 (a sys.xmltype) return sys.xmltype as begin return null; end; / | [Clob Interface] create or replace function func3 (a xmltype) return xmltype as begin return null; end; / |
예외 CASE3) SQL함수
멤버함수가 아닌 SQL함수들은 ‘.’ 연산자를 사용하여 호출되는 함수가 아니기 때문에 변환하지 않아도 됩니다.
XML Function IN SQL REFENCE: https://docs.oracle.com/database/121/SQLRF/functions002.htm#SQLRF51185
참고
GETCLOBVAL은 XMLTYPE을 CLOB TYPE으로 가져오는 함수입니다. CLOB INTERFACE에서는 이미 XMLTYPE이 CLOB이긴 때문에 해당 함수를 쓰지 않아도 됩니다.
ex) select getclobval(x.c1) from t;
-> select x.c1 from t; 수행 테스트
OBJECT_TYPE->CLOB
$ tbsql sys/tibero
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> @xmltype_install_checker
===XMLTYPE(OBJECT) IS ALREADY INSTALLED===
===XMLTYPE(OBJECT) DEPENDENCY LIST===
TIBERO.PO_XML_TAB(TABLE)
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU UNINSTALL XMLTYPE(OBJECT)
@@@@@@@@@@@@@@@@@@ ERROR: PLEASE DROP TABLES RELATED WITH XMLTYPE!! @@@@@@@@@@@@@@@@@@
SQL> desc PO_XML_TAB;
COLUMN_NAME TYPE CONSTRAINT
------------------- ------------------ ---------------
POID NUMBER
PODOC XMLTYPE XMLTYPE
SQL> create table tmp_po_xml_tab as select POID, x.podoc.getclobval() as PODOC from
po_xml_tab x; 2
Table 'TMP_PO_XML_TAB' created.
SQL> desc TMP_PO_XML_TAB;
COLUMN_NAME TYPE CONSTRAINT
------------------- ------------------ ---------------
POID NUMBER
PODOC CLOB
-- 기존 xml table drop
SQL> drop table po_xml_tab;
Table 'PO_XML_TAB' dropped.
SQL> @xmltype_install_checker.sql
===XMLTYPE(OBJECT) IS ALREADY INSTALLED===
===XMLTYPE(OBJECT) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU UNINSTALL XMLTYPE(OBJECT)
YOU CAN UNINSTALL XMLTYPE(OBJECT)!!
PSM completed.
SQL> @uninstall_xmltype.sql
Synonym 'XMLTYPE' dropped.
Type 'XMLSEQUENCETYPE' dropped.
Type 'XMLTYPE' dropped.
Package 'STANDARD_EXTENSION' created.
...
Package 'SYS.DBMS_XMLGEN' altered.
Package 'SYS.DBMS_XMLPARSER' altered.
Package 'SYS.DBMS_XSLPROCESSOR' altered.
SQL> @xmltype_install_checker.sql
XMLTYPE OID(00000000000000000000000000000001) IS VALID
===XMLTYPE(CLOB) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU INSTALL XMLTYPE(OBJECT)
YOU CAN INSTALL XMLTYPE(OBJECT)!!
PSM completed.
SQL> conn tibero/tmax
Connected to Tibero.
SQL> create table po_xml_tab (POID number, PODOC xmltype);
Table 'PO_XML_TAB' created.
SQL> insert into po_xml_tab select POID, PODOC from tmp_po_xml_tab;
1 row inserted.
SQL> commit;
Commit completed.
SQL> conn sys/tibero
Connected to Tibero.
SQL> exec UTL_RECOMP.RECOMP_SERIAL('TIBERO');
PSM completed.
SQL> conn tibero/tmax
Connected to Tibero.
SQL> select * from PO_XML_TAB;
POID PODOC
---------- --------------------------------------------------------------------------------
100
<PO> <PONO>1</PONO>
<PNAME>Po_1</PNAME>
<CUSTNAME>Jo
1 row selected.
CLOB->OBJECT TYPE
$ tbsql sys/tibero
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> @xmltype_install_checker
XMLTYPE OID(00000000000000000000000000000001) IS VALID
===XMLTYPE(CLOB) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU INSTALL XMLTYPE(OBJECT)
YOU CAN INSTALL XMLTYPE(OBJECT)!!
PSM completed.
$ tbsql tibero/tmax
tbSQL 7
TmaxTibero Corporation Copyright (c) 2020-. All rights reserved.
Connected to Tibero.
SQL> CREATE TABLE po_xml_tab(
poid number,
poDoc XMLTYPE
); 2 3 4
Table 'PO_XML_TAB' created.
SQL> INSERT INTO po_xml_tab VALUES
(100, XMLType('
<PO> <PONO>1</PONO>
<PNAME>Po_1</PNAME>
<CUSTNAME>John</CUSTNAME>
<SHIPADDR>
<STREET>1033, Main Street</STREET>
<CITY>Sunnyvalue</CITY>
<STATE>CA</STATE>
</SHIPADDR>
</PO>'))
/ 2 3 4 5 6 7 8 9 10 11 12
1 row inserted.
SQL> conn sys/tibero
Connected to Tibero.
SQL> @xmltype_install_checker
XMLTYPE OID(00000000000000000000000000000001) IS VALID
===XMLTYPE(CLOB) DEPENDENCY LIST===
TIBERO.PO_XML_TAB(TABLE)
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU INSTALL XMLTYPE(OBJECT)
@@@@@@@@@@@@@@@@@@ ERROR: PLEASE DROP TABLES RELATED WITH XMLTYPE!! @@@@@@@@@@@@@@@@@@
PSM completed.
SQL> conn tibero/tmax
Connected to Tibero.
SQL> create table tmp_po_xml_tab as select poid, getclobval(PODOC) PODOC from po_xml_tab;
Table 'TMP_PO_XML_TAB' created.
SQL> desc tmp_po_xml_tab
COLUMN_NAME TYPE CONSTRAINT
------------------- ------------------ ---------------
POID NUMBER
PODOC CLOB
SQL> drop table PO_XML_TAB;
Table 'PO_XML_TAB' dropped.
-- clob 형태인 xmltype을 object 형태로 바꾸는 절차
SQL> @install_xmltype.sql
Type 'XMLTYPE' created.
Type 'XMLSEQUENCETYPE' created.
Package 'STANDARD_EXTENSION_XML' created.
System altered.
Type 'SQLPROF_ATTR' created.
...
Package 'SYS.DBMS_METADATA' altered.
Package 'SYS.DBMS_XMLGEN' altered.
Package 'SYS.DBMS_XMLPARSER' altered.
Package 'SYS.DBMS_XSLPROCESSOR' altered.
-- xmltype 형태 확인
SQL> @xmltype_install_checker.sql
===XMLTYPE(OBJECT) IS ALREADY INSTALLED===
===XMLTYPE(OBJECT) DEPENDENCY LIST===
===================================
PLEASE CHECK DEPENDENCY LIST.
DEPENDENCY LIST WILL BE INVALIDATED IF YOU UNINSTALL XMLTYPE(OBJECT)
YOU CAN UNINSTALL XMLTYPE(OBJECT)!!
PSM completed.
SQL> conn tibero/tmax
Connected to Tibero.
SQL> create table po_xml_tab (POID number, PODOC xmltype);
Table 'PO_XML_TAB' created.
SQL> insert into po_xml_tab select POID, PODOC from tmp_po_xml_tab;
1 row inserted.
SQL> commit;
Commit completed.
SQL> conn sys/tibero
Connected to Tibero.
SQL> exec UTL_RECOMP.RECOMP_SERIAL('TIBERO');
PSM completed.
SQL> conn tibero/tmax
Connected to Tibero.
SQL> select x.podoc.getstringval() from po_xml_tab x;
X.PODOC.GETSTRINGVAL()
---------------------------------------------------------------------------
<PO> <PONO>1</PONO>
<PNAME>Po_1</PNAME>
<CUSTNAME>John</CUSTNAME>
<SHIPADDR>
<STREET>1033, Main Street</STREET>
<CITY>Sunnyvalue</CITY>
<STATE>CA</STATE>
</SHIPADDR>
</PO>
1 row selected.