ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

通过generate解析SQL日志生成xml进行SQL回放

2019-06-02 14:43:52  阅读:267  来源: 互联网

标签:xml node doc item XMLDOM SQL elmt generate


查看Oracle redo日志来分析SQL执行记录

1)设置Oracle数据字典导出路径参数(可选)

shutdown immediate
alter system set UTL_FILE_DIR='/opt/oracle/utl' scope=spfile; 
execute dbms_logmnr_d.build(dictionary_filename => 'logminer_dict.ora', dictionary_location => '/opt/oracle/utl');
startup

 

2)增加需要分析的重做日志文件(在线归档均可)

execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo01.log', options=>dbms_logmnr.new);
execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo02.log', options=>dbms_logmnr.new);
execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo03.log', options=>dbms_logmnr.new);

3)执行日志加载

使用数据字典

execute dbms_logmnr.start_logmnr(DictFileName=> '/opt/oracle/utl/logminer_dict.ora') ;

使用在线字典

execute dbms_logmnr.start_logmnr(Options=>dbms_logmnr.DICT_FROM_ONLINE_CATALOG) ;

4)查看日志

SELECT sql_redo FROM v$logmnr_contents;

5)结束分析,卸载日志
execute dbms_logmnr.end_logmnr;

 

在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括:
1.XML分析程序。即用来分析、构造和验证XML文档。
2.XPath引擎。它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。SLT处理器。它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。
3.XML SQL实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。
对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。XML分析程序由一套APIs(应用程序编程接口)构成。

===================================================================================================================================================================================

xml generate

生成Test.xml,内容如下

1 2 3 4 5 6 7 8 9 10 <staff content = "name and id">     <member>       <name>Arwen</name>     <eno>123</eno>   </member>   <member>       <name>Tom</name>     <eno>456</eno>   </member>   </staff>

 1.生成xml的plsql code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 declare     doc  XMLDOM.DOMDOCUMENT;     doc_node  XMLDOM.DOMNODE;     root_node  XMLDOM.DOMNODE;     user_node XMLDOM.DOMNODE;     item_node XMLDOM.DOMNODE;     root_elmt XMLDOM.DOMELEMENT;     user_elmt XMLDOM.DOMELEMENT;     item_elmt XMLDOM.DOMELEMENT;     item_text XMLDOM.DOMTEXT; begin    doc := XMLDOM.NEWDOMDOCUMENT;    xmldom.setVersion(doc, '1.0');    xmldom.setCharset(doc, 'UTF-8');    --根节点    doc_node := XMLDOM.MAKENODE(doc);    root_elmt := XMLDOM.CREATEELEMENT(doc,'staff');    XMLDOM.SETATTRIBUTE(root_elmt,'content ','name and id');    root_node:=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(root_elmt));       --节点1    user_elmt := XMLDOM.CREATEELEMENT(doc,'member');    user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));         item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');      item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));      item_text := XMLDOM.CREATETEXTNODE(doc,'Arwen');      item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));            item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');      item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));      item_text := XMLDOM.CREATETEXTNODE(doc,'123');      item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));            --节点2      user_elmt := XMLDOM.CREATEELEMENT(doc,'member');      user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));         item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');      item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));      item_text := XMLDOM.CREATETEXTNODE(doc,'tom');      item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));            item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');      item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));      item_text := XMLDOM.CREATETEXTNODE(doc,'456');      item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));            --写入操作系统文件中      XMLDOM.WRITETOFILE(doc,'DIR'||'\Test.xml');--注意必须先创建一个文件目录dir      --可以通过语句 : create or replace directory dir as 'd:\temp'         XMLDOM.FREEDOCUMENT(doc);  end;

 2.将xml encode 成clob 写入文件:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 declare     l_f utl_file.file_type;     clobpart varchar2(2048);     offset integer;     l_xmltype XMLTYPE;     cloblen integer;     response_clob CLOB;     resp_domdoc DBMS_XMLDOM.DOMDOCUMENT; begin     l_f  := utl_file.fopen('TEST_DIR',l_full_file_name,'w');     utl_file.put_line(l_f,'<?xml version="1.0" encoding="utf-8" standalone="yes"?>'||chr(13));     resp_domdoc := SoapEncPrcnScnrPckgRead.encd_root_prcn_scnr_pckg_read(p_psp_resp_doc);     l_xmltype := dbms_xmldom.getXmlType(resp_domdoc);     dbms_xmldom.freeDocument(resp_domdoc);     response_clob := l_xmltype.getClobVal;     cloblen := LENGTH(response_clob);     while offset < cloblen     loop         clobPart := dbms_lob.substr(response_clob, 1024, offset);         utl_file.put(l_f, clobPart);         offset := offset + 1024;     end loop;     utl_file.fflush(l_f);     utl_file.fclose(l_f); end; /

 3.结合使用XMLDOM和utl_file
    这样生成XML文件非常方便,能满足一般的应用了.但是XMLDOM有个缺点,就是一次性在内存中生成所有xml文件内容,然后写入到磁盘文件中.如果 xml文件太大,比如说有个table有几个G,想把它保存成xml文件.这样可能就会出现内存不足,生成文件失败.那该咋整呢?
    可能首先想到的是用UTL_FILE去生成文件.
    里面的内容全部手动写成xml格式的,然后保存成xml后缀的文件.这样确实可行.但有个麻烦问题时如果一些节点内容含有xml的五个保留字符的话 (&,<,>,'," 分别是和号,小于号,大于号,单引号,双引号),我们如果以文本方式打开xml文件是看不到节点内容里面有这些保留字的,都转换成了对应 的&amp, &gt, &lt, &apos, &quot.节点指定的是上面的Arwen或123,假如有名字(A&r<w>e'n")则保存到xml文件中应该改成 (A&ampr&gtw&lte&aposn&quot).如果用xmldom会默认去转换,不用我们管了.如 果用UTL_FILE必须手动写代码去转换.
    假如有表staff(name varchar2(30), eno integer),里面有几个G的内容,要转换成开头讲的那种格式的xml文件。
    --生成xml的代码其中XML文件的头和尾用UTL_FILE直接写入文件中,节点内容用xmldom生成,然后写到clob变量中,再把clob变量值用utl_file写入到xml文件中。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 declare   STAFFINFO  UTL_FILE.FILE_TYPE;   v_temp clob;   cursor c_table_info is select name,eno from staff;   v_name varchar2(30);   v_eno integer;   doc  XMLDOM.DOMDOCUMENT;   doc_node XMLDOM.DOMNODE;   root_node XMLDOM.DOMNODE;   user_node XMLDOM.DOMNODE;   item_node XMLDOM.DOMNODE;   root_elmt XMLDOM.DOMELEMENT;   user_elmt XMLDOM.DOMELEMENT;   item_elmt XMLDOM.DOMELEMENT;   item_text XMLDOM.DOMTEXT; begin    --xml header     STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','W',32767);--跟前面说的一样必须先创建一个directory才行     UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,'<staff content = "name and id">');     UTL_FILE.FFLUSH(STAFFINFO );--直接写入到磁盘文件中,不会停留在内存中     UTL_FILE.FCLOSE(STAFFINFO );         open c_table_info;         loop             fetch c_table_info into v_name,v_eno;             exit when c_table_info%notfound;        --XML节点           doc := XMLDOM.NEWDOMDOCUMENT;         xmldom.setCharset(doc, 'UTF-8');       doc_node := XMLDOM.MAKENODE(doc);       user_elmt := XMLDOM.CREATEELEMENT(doc,'member');            user_node :=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(user_elmt));       item_elmt :=XMLDOM.CREATEELEMENT(doc,'name');       item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));       item_text := XMLDOM.CREATETEXTNODE(doc,v_name);       item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));       item_elmt :=XMLDOM.CREATEELEMENT(doc,'eno');       item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));       item_text := XMLDOM.CREATETEXTNODE(doc,'eno');       item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));       v_temp :=' ';         --写入到临时变量v_temp中       XMLDOM.WRITETOCLOB(doc,v_temp);       STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','A',32767);--以a模式会在文件后添加内容,用w会覆盖之前的内容       UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,v_temp);       UTL_FILE.FFLUSH(STAFFINFO );       UTL_FILE.FCLOSE(STAFFINFO );       XMLDOM.FREEDOCUMENT(doc);     end loop;     close c_table_info;     --xml tail     STAFFINFO :=utl_file.fopen_nchar('DIR','Test.xml','a',32767);     UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,'</staff>');     UTL_FILE.FFLUSH(STAFFINFO );     UTL_FILE.FCLOSE(STAFFINFO ); end;

 

标签:xml,node,doc,item,XMLDOM,SQL,elmt,generate
来源: https://www.cnblogs.com/klb561/p/10962866.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有