xml db 操作

1.存储XML到表中:

  1)创建带XMLTYPE字段的表:

         CREATE TABLE xmltable OF XMLTYPE;这里创建了一个只含一个XMLTYPE字段的表

         CREATE TABLE xmlcontent (id number(19) primary key,xmlvalue XMLTYPE);这里创建了一个有主键和一个XMLTYPE字段的表

  2)创建逻辑目录,用于存放被存入的XML文件

        CREATE DIRECTORY xmldir AS '路径名';

         注意:上面的路径名是已经存在的,并且将要存储的XML文件放进该目录下

  3)读取XML文件的内容

   CREATE OR REPLACE FUNCTION getclobdocument(

    filename  in  varchar2,

    charset   in  varchar2  default null)

     RETURN  clob DETERMINISTIC

     IS

     charContent  clob:='';

     file  bfile:=bfilename('xmldir',filename);--路径名+xml文件名组成抽象文件路径--

     targetFile bfile:;

     charset_id  number:=1;

     dest_offset  number:=1;

     src_offset   number:=1;

     lang_ctx      number:=DBMS_LOB.default_lang_ctx;

     warning    number:=0;

     BEGIN

     DBMS_LOB.CREATETEMPORARY(charContent,true);--初始化LOB的Locator--

     IF charset IS NOT NULL  THEN

      charset_id:=NLS_CHARSET_ID(charset);

     END IF;

     targetFile:= file;

     DBMS_LOB.fileopen(targetFile,DBMS_LOB.file_readonly);--打开文件--

     DBMS_LOB.loadclobfromfile(charContent,targetFile,DBMS_LOB.getlength(targetFile),dest_offset,src_offset,charset_id,lang_ctx,warning);--读取文件,读取前要先初始化LOB(CLOB,BLOB的Locator)--

     DBMS_LOB.fileclose(targetFile);--关闭文件--

     RETURN charContent;--返回XML文件的内容--

     END;



     INSERT INTO xmlcontent values(1,XMLTYPE(getclobdocument('xml文件名')));--xml文件名不含路径名--

     INSERT INTO xmltable values(XMLTYPE(getclobdocument('xml文件名')));



2.更新XML表数据

   1)普通更新

      UPDATE xmlcontent SET xmlvalue=XMLTYPE(getclobdocument('xml文件名'));

      UPDATE xmltable t SET VALUE(t)=XMLTYPE(getclobdocument('xml文件名'));--因为xmltable里只有一个字段,而是用上面特殊的方式创建表,所以VALUE(表别名)可指向该字段。注意VALUE(表名)是非法的;若不是用特殊方法建表,不能这样写--有待研究

  2)更新节点值

     UPDATE xmlcontent SET xmlvalue=UPDATEXML(xmlvalue,'节点路径/text()','新值');

--UPDATEXML(存放XML的字段名,'节点路径/text()','新值'),节点路径形式:/根元素/子元素/。。。/text(),例:/book/name/text()--

     注意:当要更改的节点形如<a/>时,就不能直接修改节点值,而要将整个节点换掉。

  3)更新节点树

     UPDATE xmlcontent SET xmlvalue=UPDATEXML(xmlvalue,'节点路径',XMLTYPE('新的节点形式'));

--节点路径,用于指定要替换的节点;XMLTYPE('新的节点形式'),可以一个节点,也可为一棵树。例:

UPDATEXML(xmlvalue,'/book/name',XMLTYPE('<hey><key>new</key></hey>')),此时子元素<name></name>将消失,其位置由<hey><key>new</key></hey>代替--

   4)更新属性值,获取属性值
select extractvalue(t.bwxx,'/ZFLX/Record/Row[1]/@Sdxmmc') from  gs_xtxj.xtxj_gzwj t

update gs_xtxj.xtxj_gzwj t set t.bwxx = updatexml(t.bwxx,'/ZFLX/Record/Row[1]/@Sdxmmc','aaaa');
commit;

3.从数据库读取XML

1)existsNode(XMLTYPE字段名,'节点路径'),检查节点路径是否存在,存在着返回1,否则返回0;

   节点路径:这里不单单只是形如/book/name,还可以是/book[name="指定值"]或/book/name[@attribute="指定值"]等;

/book[name="指定值"],表示查询子节点值为指定值的父节点book是否存在。

/book/name[@attribute="指定值"],表示查询节点属性值为指定值的节点name是否存在。



2)extractValue(XMLTYPE字段名,'节点路径'),获取指定路径节点的值,不管节点路径的形式如何(即使像上面1)中那样)都是取最后的一个节点的值。若给节点不存在,则取空值的;若该节点多于一个,就会出错。

例:

  SELECT extractValue(XMLTYPE字段名,'节点路径') from 表名;



3)extract(XMLTYPE字段名,'节点路径'),获取指定路径的节点及其子节点数,返回值为CLOB。若有N个节点,就返回N条记录。若节点不存在,则返回空的CLOB

注意:select extract(XMLTYPE字段名,'节点路径').getclobval() from 表名,一定要加.getclobval()才能显示出来,否则大数据字段是不能显示的。



4)利用table()和xmlsequence()返回多个节点值(继续研究)

例:

   select extractValue(value(t),'/name') from xmlcontent,table(xmlsequence(extract(xmlvalue,'/book/name'))) t;



5)根据子节点值查询

/*根据子节点值查询,[子节点名="值"],这里id的父节点为chapter,现在要查询子节点id值为13的父节点下的content节点,而content节点和id节点为兄弟节点*/
select  extract(xml_file,'/book/chapter[id="13"]/content').getclobval() from  t_content_metadata where metadata_id=100000311012;



6)根据节点属性查询

/*根据节点属性查询,[@属性="值"],这里name为chapter节点的属性,现在要查询节点属性为n的chapter节点下的id节点*/
select extract(xml_file,'/book/chapter[@name="n"]/id').getclobval() from  t_content_metadata where metadata_id=100000311012;



7)获取节点属性值

/*获取节点属性值,这里是获取子节点num值为hhh的父节点chapter的id属性的值*/
select extract(xml_file,'/book/chapter[num="hhh"]/@id').getStringval() from  t_content_metadata where metadata_id=100000311012;



select extractvalue(xml_file,'/book/chapter[num="hhh"]/@id') from  t_content_metadata where metadata_id=100000311012;



8)extract获取节点值

/*获取节点值,这里是获取子节点num值为hhh的父节点chapter的子节点name的值,name和num为兄弟节点*/
select extract(xml_file,'/book/chapter[num="hhh"]/name/text()').getStringval() from  t_content_metadata where metadata_id=100000311012;

它与extractvalue的区别是,它会把<>....</>内的内容全部取出 ,而extractvalue会过滤掉xml的标签。

如:<a><![CDATA[hahaha]]></a>

extract,显示:<![CDATA[hahaha]]>;

extractvalue,显示:hahaha。

而写成

select extractvalue(xml_file,'/book/chapter[num="hhh"]/name/text()').getStringval() from  t_content_metadata where metadata_id=100000311012;是没问题的,不过是多余而已。





4.增加删除XML数据

1)利用APPENDCHILDXML追加数据

/*在指定节点内的最尾加入新的节点,<a></a>会自动转化为<a/>
第三个参数一定要XMLTYPE(),而XMLTYPE()内的字符串必须符合XML语法规范的,
否则会出错;不能一次加入多个同一级的节点,如<h></h><b></b>*/

例:

update t_content_metadata
set xml_file=appendchildxml(xml_file,'/info',xmltype('<huang>wa</huang>'))
where metadata_id=100000311012;

2)利用DELETEXML删除数据

*将指定的节点删除,被删除的节点的子节点都会被同时删除;若无加限制条件,将删除同一级相同名称的节点;
若在节点路径后加[num],num从1开始,表示同名第几个子节点,能准确地删除*/

例:update t_content_metadata
set xml_file=deletexml(xml_file,'/info/huang[1]')
where metadata_id=100000311012

3)利用INSERTCHILDXML,在指定的节点后面添加相同类型的新节点

/*将新节点插入到指定的路径下,新节点必须与指定的子节点相同,但属性和值可以不同;新节点的位置紧跟在最后一个指定子节点后面;只能插入已存在的节点类型,若不原来没有该节点,则要用appendchildxml();第三个参数必须为XMLTYPE()*/

例:update t_content_metadata
set xml_file=INSERTCHILDXML(xml_file,'/info','h',xmltype('<h>3</h>'))
where metadata_id=100000311012;

4)利用INSERTXMLBEFORE,在指定的节点前添加新节点

/*将新节点放在路径指点的节点前,与路径指定的节点在同一级;若路径指定的节点存在多个,就在符合条件的节点前都新增新节点;第三个参数必须为XMLTYPE()*/

例:update t_content_metadata
set xml_file=INSERTXMLBEFORE(xml_file,'/info/h','s')
where metadata_id=100000311012;

猜你喜欢

转载自yjxin0302.iteye.com/blog/1617360