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;
xml db 操作
猜你喜欢
转载自yjxin0302.iteye.com/blog/1617360
今日推荐
周排行