Oracle xmltype是从Oracle 9i开始支持一种新的数据类型,用于存储和管理xml数据,并提供了很多的functions,用来保存、检索和操作xml文档和管理节点。XMLType是系统定义的类型,所以可以使用它作为一个函数的参数或表或视图中的列的数据类型。也可以创建表和视图的XMLType。当你创建一个表中的一个XMLType列,你可以选择XML数据存储在一个CLOB列,作为二进制XML(内部存储为CLOB),或对象的关系。
下面将介绍Oracle XMLType的一些基本使用。
1、创建一个包含XMLType类型列的表,并插入测试数据
zx@TEST>createtablet1(idnumber,xml_datasys.xmltype); Tablecreated. zx@TEST>desct1 Name Null? Type --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ID NUMBER XML_DATA SYS.XMLTYPE zx@TEST>insertintot1values(1,'abc'); insertintot1values(1,'abc') * ERRORatline1: ORA-31011:XMLparsingFailed ORA-19202:ErroroccurredinXMLprocessing LPX-00210:expected'<'insteadof'a' Erroratline1 zx@TEST>insertintot1values(1,'<abc>1</abc>'); 1rowcreated. zx@TEST>colxml_datafora80 zx@TEST>select*fromt1; IDXML_DATA ------------------------------------------------------------------------------------------ 1<abc>1</abc>
从上面看出,XMLType可以做为列中列的数据类型,在插入数据时必须符合XML格式才能插入,否则会报错。
2、查看XMLType的存储形式
从user_segments视图中看出XMLType列是以LOB字段存储的
zx@TEST>selectsegment_name,segment_typefromuser_segments; SEGMENT_NAME SEGMENT_TYPE ------------------------------------------------------------------------------------ T1 TABLE SYS_IL0000074607C00003$$LOBINDEX SYS_LOB0000074607C00003$$LOBSEGMENT
查看user_lobs是否对应xml_data列
zx@TEST>colcolumn_namefora30 zx@TEST>coltable_namefora30 zx@TEST>selecttable_name,column_name,segment_namefromuser_lobs; TABLE_NAME COLUMN_NAME SEGMENT_NAME ------------------------------------------------------------------------------------------ T1 SYS_NC00003$ SYS_LOB0000074607C00003$$
从上面的查询结果可以看到LOBSEGMENT对应的表T1中的列SYS_NC00003$,而不是XML_DATA列,而且表T1中没有这个列,再次查询user_tab_cols视图
zx@TEST>coldata_typefora30 zx@TEST>selectTABLE_NAME,COLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN,COLUMN_IDfromuser_tab_cols; TABLE_NAME COLUMN_NAME DATA_TYPE HIDDEN_CO COLUMN_ID ------------------------------------------------------------------------------------------------------------- T1 ID NUMBER NO 1 T1 XML_DATA XMLTYPE NO 2 T1 SYS_NC00003$ CLOB YES 2
从上面的查询中可以看出列SYS_NC00003$是表T1中的隐藏列,它与列XML_DATA列的COLUMN_ID都是2,说明它们是同一列。由此可以看出XMLType类型的数据由CLOB类型列协助保存。由下面的表定义也可以推断出这一点:
zx@TEST>selectdbms_Metadata.get_ddl('TABLE','T1',USER)fromdual; DBMS_MetaDATA.GET_DDL('TABLE',USER) -------------------------------------------------------------------------------- CREATETABLE"ZX"."T1" ( "ID"NUMBER,"XML_DATA""SYS"."XMLTYPE" )SEGMENTCREATIONIMMEDIATE PCTFREE10PCTUSED40INITRANS1MAXTRANS255NOCOMPRESSLOGGING STORAGE(INITIAL65536NEXT1048576MINEXTENTS1MAXEXTENT S2147483645 PCTINCREASE0FREELISTS1FREELISTGROUPS1BUFFER_POOLDEFAULT FLASH_CACHEDEFAULTCELL_FLASH_CACHEDEFAULT) TABLESPACE"USERS" XMLTYPECOLUMN"XML_DATA"STOREASBASICFILECLOB( TABLESPACE"USERS"ENABLESTORAGEINROWCHUNK8192PCTVER SION10 NOCACHELOGGING STORAGE(INITIAL65536NEXT1048576MINEXTENTS1MAXEXTENTS2147483645 PCTINCREASE0FREELISTS1FREELISTGROUPS1BUFFER_POOL DEFAULTFLASH_CACHEDEFAULTCELL_FLASH_CACHEDEFAUL T))
3、关于XML的一些函数
1) sys.xmltype.createxml函数
使用sys.xmltype.createxml创建XMLType类型的数据
zx@TEST>insertintot1values(2,2sys.xmltype.createxml('<?xmlversion="1.0"encoding="UTF-8"?> 3<collectionxmlns=""> 4<record> 5<leader>-----nam0-22-----^^^450-</leader> 6<datafieldtag="200"ind1="1"ind2=""> 7<subfieldcode="a">抗震救灾</subfield> 8<subfieldcode="f">奥运会</subfield> 9</datafield> 10<datafieldtag="209"ind1=""ind2=""> 11<subfieldcode="a">经济学</subfield> 12<subfieldcode="b">计算机</subfield> 13<subfieldcode="c">10001</subfield> 14<subfieldcode="d">2005-07-09</subfield> 15</datafield> 16<datafieldtag="610"ind1="0"ind2=""> 17<subfieldcode="a">计算机</subfield> 18<subfieldcode="a">笔记本</subfield> 19</datafield> 20</record> 21</collection>')); 1rowcreated. zx@TEST>commit; Commitcomplete. zx@TEST>colxml_datafora80 zx@TEST>select*fromt1; IDXML_DATA ------------------------------------------------------------------------------------------ 2<?xmlversion="1.0"encoding="UTF-8"?> <collectionxmlns=""> <record> <leader>-----nam0-22-----^^^450-</leader> <datafieldtag="200"ind1="1"ind2=""> <subfieldcode="a">抗震救灾</subfield> <subfieldcode="f">奥运会</subfield> </datafield> <datafieldtag="209"ind1=""ind2=""> <subfieldcode="a">经济学</subfield> <subfieldcode="b">计算机</subfield> <subfieldcode="c">10001</subfield> <subfieldcode="d">2005-07-09</subfield> </datafield> <datafieldtag="610"ind1="0"ind2=""> <subfieldcode="a">计算机</subfield> <subfieldcode="a">笔记本</subfield> </datafield> </record> </collection>
2) extractvalue函数
extractvalue函数提供对XML文件的检索功能只能返回一个节点的一个值,如果该节点有多个值,则系统提示错误。
zx@TEST>coldatafora80 zx@TEST>selectextractvalue(i.xml_data,'/collection/record/leader')datafromt1i; DATA -------------------------------------------------------------------------------- -----nam0-22-----^^^450- zx@TEST>selectextractvalue(i.xml_data,'/collection/record/datafield')datafromt1i; selectextractvalue(i.xml_data,'/collection/record/datafield')datafromt1i * ERRORatline1: ORA-19025:EXTRACTVALUEreturnsvalueofonlyonenode
3)extract函数
extract函数查询XMLType的内容,它可以返回一个节点下的所有值。它返回的是XML格式的。
zx@TEST>selectextract(i.xml_data,'/collection/record/datafield/subfield')datafromt1i; DATA -------------------------------------------------------------------------------- <subfieldxmlns=""code="a">抗震救灾</subfield><subfieldxmlns=""code="f">奥运 会</subfield><subfieldxmlns=""code="a">经济学</subfield><subfieldxmlns=""cod e="b">计算机</subfield><subfieldxmlns=""code="c">10001</subfield><subfieldxml ns=""code="d">2005-07-09</subfield><subfieldxmlns=""code="a">计算机</subfield ><subfieldxmlns=""code="a">笔记本</subfield>
查询tag="610",且code="a"所对应的值
zx@TEST>selectextract(i.xml_data,'/collection/record/datafield[@tag="610"]/subfield[@code="a"]')datafromt1i; DATA -------------------------------------------------------------------------------- <subfieldxmlns=""code="a">计算机</subfield><subfieldxmlns=""code="a">笔记本< /subfield>
4) table和XMLSequence
如果只想返回它值就要是用上面的两个函数了。
zx@TEST>selectextractvalue(value(i),'/subfield')data 2fromt1x,3table(xmlsequence(extract(x.xml_data,'/collection/record/datafield[@tag="610"]/subfield[@code="a"]')))i; DATA -------------------------------------------------------------------------------- 计算机 笔记本
4) updatexml
使用updatexml更新XMLType里的内容,把tag="209"、code="a"的经济学修改为“赵旭”
zx@TEST>updatet1setxml_data= 2updatexml(xml_data,'/collection/record/datafield[@tag="209"]/subfield[@code="a"]/text()','赵旭'); 1rowupdated. zx@TEST>select*fromt1; IDXML_DATA ------------------------------------------------------------------------------------------ 2<?xmlversion="1.0"encoding="UTF-8"?> <collectionxmlns=""> <record> <leader>-----nam0-22-----^^^450-</leader> <datafieldtag="200"ind1="1"ind2=""> <subfieldcode="a">抗震救灾</subfield> <subfieldcode="f">奥运会</subfield> </datafield> <datafieldtag="209"ind1=""ind2=""> <subfieldcode="a">赵旭</subfield> <subfieldcode="b">计算机</subfield> <subfieldcode="c">10001</subfield> <subfieldcode="d">2005-07-09</subfield> </datafield> <datafieldtag="610"ind1="0"ind2=""> <subfieldcode="a">计算机</subfield> <subfieldcode="a">笔记本</subfield> </datafield> </record> </collection>
参考:http://blog.csdn.net/r_youxia_dayu/article/details/6686106
http://database.51cto.com/art/200911/163928.htm
http://blog.itpub.net/17203031/viewspace-708738/
官方文档:
http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/t_xml.htm#ARPLS369
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions225.htm#SQLRF06172
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions060.htm#SQLRF00640
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions061.htm#SQLRF06173
原文链接:https://www.f2er.com/oracle/210201.html