Using XML Datatype Columns
Peter Goldthorp June 2002
The xmltype datatype is new in Oracle 9i. It can be used to store well formed xml documents. 9.0.1 allows you to query these documents via XPATH. Examples:
Create a sequence and a table to hold the xml:
create sequence xml_element_seq; create table xml_load_data( id number(22) constraint xml_element_pk primary key, xml_content sys.xmltype constraint xml_el_content_nn not null);
Insert a row into the table using data identified by a uri column in a separate table:
insert into xml_load_data (select xml_element_seq.nextval, sys.XMLType.createXML(e.url.getClob()) from metadata_uri e where e.name = 'AD_BUGS')
Query the contents of an xml file (listed below). Return an xml fragment:
select e.xml_content.extract('/ROWSET/ROW/TABLE_T/SCHEMA_OBJ').getStringVal() schema_data from xml_load_data e where id = 2; SCHEMA_DATA --------------------------------------------- <SCHEMA_OBJ> <OBJ_NUM>31926</OBJ_NUM> <DATAOBJ_NUM>31926</DATAOBJ_NUM> <OWNER_NUM>50</OWNER_NUM> <OWNER_NAME>APPLSYS</OWNER_NAME> <NAME>AD_BUGS</NAME> <NAMESPACE>1</NAMESPACE> <TYPE_NUM>2</TYPE_NUM> <CTIME>22-JAN-02</CTIME> <MTIME>22-JAN-02</MTIME> <STIME>22-JAN-02</STIME> <STATUS>1</STATUS> <FLAGS>0</FLAGS> <SPARE1>6</SPARE1> <SPARE2>1</SPARE2> </SCHEMA_OBJ>
Use the text() function to return the contents of an XML element:
select e.xml_content.extract('/ROWSET/ROW/TABLE_T/SCHEMA_OBJ/NAME/text()').getStringVal() table_name from xml_load_data e where id = 2; TABLE_NAME -------------------------- AD_BUGS
Query elements in a repeating group. Note that these query returns return a single row:
select e.xml_content.extract('/ROWSET/ROW/TABLE_T/COL_LIST/COL_LIST_ITEM/NAME').getStringVal() all_columns from xml_load_data e where id = 2; ALL_COLUMNS --------------------------------------- <NAME>BUG_ID</NAME> <NAME>APPLICATION_SHORT_NAME</NAME> <NAME>BUG_NUMBER</NAME> <NAME>CREATION_DATE</NAME> <NAME>ARU_RELEASE_NAME</NAME> <NAME>BUG_STATUS</NAME> <NAME>SUCCESS_FLAG</NAME> <NAME>CREATED_BY</NAME> <NAME>LAST_UPDATE_DATE</NAME> <NAME>LAST_UPDATED_BY</NAME> select e.xml_content.extract('/ROWSET/ROW/TABLE_T/COL_LIST/COL_LIST_ITEM/NAME').getStringVal() columns , e.xml_content.extract('/ROWSET/ROW/TABLE_T/COL_LIST/COL_LIST_ITEM/LENGTH').getStringVal() lengths from xml_load_data e where id = 2; COLUMNS ------------------------------------- LENGTHS ------------------------------------- <NAME>BUG_ID</NAME> <NAME>APPLICATION_SHORT_NAME</NAME> <NAME>BUG_NUMBER</NAME> <NAME>CREATION_DATE</NAME> <NAME>ARU_RELEASE_NAME</NAME> <NAME>BUG_STATUS</NAME> <NAME>SUCCESS_FLAG</NAME> <NAME>CREATED_BY</NAME> <NAME>LAST_UPDATE_DATE</NAME> <NAME>LAST_UPDATED_BY</NAME> <LENGTH>22</LENGTH> <LENGTH>50</LENGTH> <LENGTH>30</LENGTH> <LENGTH>7</LENGTH> <LENGTH>30</LENGTH> <LENGTH>30</LENGTH> <LENGTH>1</LENGTH> <LENGTH>22</LENGTH> <LENGTH>7</LENGTH> <LENGTH>22</LENGTH> 1 row selected.
Use the index element notation to identify a single element in a repeating group:
select e.xml_content.extract('/ROWSET/ROW/TABLE_T/COL_LIST/COL_LIST_ITEM[1]/NAME').getStringVal() col_name from xml_load_data e where id = 2; COL_NAME --------------------- <NAME>BUG_ID</NAME>
Here is the xml file used in the examples above:
<?xml version="1.0"?> <ROWSET> <ROW> <TABLE_T> <VERS_MAJOR>1</VERS_MAJOR> <VERS_MINOR>0</VERS_MINOR> <OBJ_NUM>31470</OBJ_NUM> <SCHEMA_OBJ> <OBJ_NUM>31470</OBJ_NUM> <DATAOBJ_NUM>31470</DATAOBJ_NUM> <OWNER_NUM>49</OWNER_NUM> <OWNER_NAME>APPLSYS</OWNER_NAME> <NAME>AD_BUGS</NAME> <NAMESPACE>1</NAMESPACE> <TYPE_NUM>2</TYPE_NUM> <CTIME>28-DEC-01</CTIME> <MTIME>28-DEC-01</MTIME> <STIME>28-DEC-01</STIME> <STATUS>1</STATUS> <FLAGS>0</FLAGS> <SPARE1>6</SPARE1> <SPARE2>1</SPARE2> </SCHEMA_OBJ> <STORAGE> <FILE_NUM>7</FILE_NUM> <BLOCK_NUM>393</BLOCK_NUM> <TYPE_NUM>5</TYPE_NUM> <TS_NUM>7</TS_NUM> <BLOCKS>128</BLOCKS> <EXTENTS>1</EXTENTS> <INIEXTS>200</INIEXTS> <MINEXTS>1</MINEXTS> <MAXEXTS>2147483645</MAXEXTS> <EXTSIZE>128</EXTSIZE> <EXTPCT>0</EXTPCT> <USER_NUM>49</USER_NUM> <LISTS>4</LISTS> <GROUPS>4</GROUPS> <BITMAPRANGES>0</BITMAPRANGES> <CACHEHINT>0</CACHEHINT> <SCANHINT>0</SCANHINT> <HWMINCR>31470</HWMINCR> <FLAGS>1</FLAGS> </STORAGE> <TS_NAME>USERS</TS_NAME> <BLOCKSIZE>8192</BLOCKSIZE> <DATAOBJ_NUM>31470</DATAOBJ_NUM> <COLS>10</COLS> <PCT_FREE>10</PCT_FREE> <PCT_USED>60</PCT_USED> <INITRANS>10</INITRANS> <MAXTRANS>255</MAXTRANS> <FLAGS>17</FLAGS> <AUDIT_VAL>--------------------------------</AUDIT_VAL> <ROWCNT>0</ROWCNT> <BLKCNT>0</BLKCNT> <EMPCNT>251</EMPCNT> <AVGSPC>0</AVGSPC> <CHNCNT>0</CHNCNT> <AVGRLN>0</AVGRLN> <AVGSPC_FLB>0</AVGSPC_FLB> <FLBCNT>0</FLBCNT> <ANALYZETIME>28-DEC-01</ANALYZETIME> <SAMPLESIZE>0</SAMPLESIZE> <INTCOLS>10</INTCOLS> <KERNELCOLS>10</KERNELCOLS> <PROPERTY>536870912</PROPERTY> <TRIGFLAG>0</TRIGFLAG> <SPARE1>238</SPARE1> <COL_LIST> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>1</COL_NUM> <INTCOL_NUM>1</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>BUG_ID</NAME> <TYPE_NUM>2</TYPE_NUM> <LENGTH>22</LENGTH> <CHARSETID>0</CHARSETID> <CHARSETFORM>0</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001902</NAME> <CON_NUM>1902</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>0</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>2</COL_NUM> <INTCOL_NUM>2</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>APPLICATION_SHORT_NAME</NAME> <TYPE_NUM>1</TYPE_NUM> <LENGTH>50</LENGTH> <CHARSETID>46</CHARSETID> <CHARSETFORM>1</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001903</NAME> <CON_NUM>1903</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>50</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>3</COL_NUM> <INTCOL_NUM>3</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>BUG_NUMBER</NAME> <TYPE_NUM>1</TYPE_NUM> <LENGTH>30</LENGTH> <CHARSETID>46</CHARSETID> <CHARSETFORM>1</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001904</NAME> <CON_NUM>1904</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>30</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>4</COL_NUM> <INTCOL_NUM>4</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>CREATION_DATE</NAME> <TYPE_NUM>12</TYPE_NUM> <LENGTH>7</LENGTH> <CHARSETID>0</CHARSETID> <CHARSETFORM>0</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001905</NAME> <CON_NUM>1905</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>0</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>5</COL_NUM> <INTCOL_NUM>5</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>ARU_RELEASE_NAME</NAME> <TYPE_NUM>1</TYPE_NUM> <LENGTH>30</LENGTH> <CHARSETID>46</CHARSETID> <CHARSETFORM>1</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001906</NAME> <CON_NUM>1906</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>30</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>6</COL_NUM> <INTCOL_NUM>6</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>BUG_STATUS</NAME> <TYPE_NUM>1</TYPE_NUM> <LENGTH>30</LENGTH> <CHARSETID>46</CHARSETID> <CHARSETFORM>1</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001907</NAME> <CON_NUM>1907</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>30</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>7</COL_NUM> <INTCOL_NUM>7</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>SUCCESS_FLAG</NAME> <TYPE_NUM>1</TYPE_NUM> <LENGTH>1</LENGTH> <CHARSETID>46</CHARSETID> <CHARSETFORM>1</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001908</NAME> <CON_NUM>1908</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>1</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>8</COL_NUM> <INTCOL_NUM>8</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>CREATED_BY</NAME> <TYPE_NUM>2</TYPE_NUM> <LENGTH>22</LENGTH> <CHARSETID>0</CHARSETID> <CHARSETFORM>0</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001909</NAME> <CON_NUM>1909</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>0</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>9</COL_NUM> <INTCOL_NUM>9</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>LAST_UPDATE_DATE</NAME> <TYPE_NUM>12</TYPE_NUM> <LENGTH>7</LENGTH> <CHARSETID>0</CHARSETID> <CHARSETFORM>0</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001910</NAME> <CON_NUM>1910</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>0</SPARE3> </COL_LIST_ITEM> <COL_LIST_ITEM> <OBJ_NUM>31470</OBJ_NUM> <COL_NUM>10</COL_NUM> <INTCOL_NUM>10</INTCOL_NUM> <PROPERTY>0</PROPERTY> <NAME>LAST_UPDATED_BY</NAME> <TYPE_NUM>2</TYPE_NUM> <LENGTH>22</LENGTH> <CHARSETID>0</CHARSETID> <CHARSETFORM>0</CHARSETFORM> <CON> <OWNER_NUM>49</OWNER_NUM> <NAME>SYS_C001911</NAME> <CON_NUM>1911</CON_NUM> <OBJ_NUM>31470</OBJ_NUM> <NUMCOLS>1</NUMCOLS> <CONTYPE>7</CONTYPE> <ENABLED>1</ENABLED> <INTCOLS>1</INTCOLS> <MTIME>28-DEC-01</MTIME> <FLAGS>12</FLAGS> </CON> <SPARE1>0</SPARE1> <SPARE2>0</SPARE2> <SPARE3>0</SPARE3> </COL_LIST_ITEM> </COL_LIST> <CON0_LIST/> <CON1_LIST/> <CON2_LIST/> </TABLE_T> </ROW> </ROWSET>