在數據開發中,有時你須要合併兩個動態遊標sys_refcursor
。sql
開發一個存儲過程PROC_A,這個過程業務邏輯至關複雜,代碼篇幅較長。一段時間後要開發一個PROC_B,要用PROC_A一樣的邏輯,並且在這個過程當中,還要循環調用PROC_A這個過程。擺在你面前的有兩個選擇。oracle
好吧,這個新的過程是完成了,但是看上去,它更復雜了,代碼量更大了。徹底不能接受,必須改改!
這時,已經默默打開了ORACLE官方幫助文檔 https://docs.oracle.com/cd/B1...,尋找一個可行的辦法,最終目標標是要解析,整合,合併 遊標 sys_refcursorapp
通過搜索查詢,找到如下可行的方案dom
爲此你須要掌握的知識有函數
從上邊的幫助文檔中,知道xmltype的構造函數中能夠直接傳入遊標xmltype(refcursor)
從而獲得一個xmltype,調用xmltype的getClobVal
方法,可獲得序列化的結果,因此它的結構是這樣的code
<?xml version="1.0"?> <ROWSET> <ROW> <COLUMNNAME1></COLUMNNAME1> <COLUMNNAME2></COLUMNNAME2> <...>...</...> </ROW> .... </ROWSET>
因此,若是須要合併兩個數據列相同遊標,只須要提取DOM中的ROW節點數據保存到定義的clob字段中去。server
提取dom中片斷,採用標準的xpath語法,/*/ROW
這裏提取ROW信息xml
Declare x xmltype; rowxml clob; mergeXml clob; ref_cur Sys_Refcursor; ref_cur2 Sys_Refcursor; ref_cur3 Sys_Refcursor; begin open ref_cur for select F_USERNAME, F_USERCODE, F_USERID from Tb_System_User where F_userid = 1; Dbms_Lob.createtemporary(mergeXml, true); Dbms_Lob.writeappend(mergeXml, 8, '<ROWSET>'); x := xmltype(ref_cur); Dbms_Output.put_line('=====完整的REFCURSOR結構====='); Dbms_Output.put_line(x.getClobVal()); Dbms_Output.put_line('=====只提取行信息====='); rowxml := x.extract('/ROWSET/ROW').getClobVal(0, 0); Dbms_Output.put_line(rowxml); Dbms_Lob.append(mergeXml, rowxml);ROWSET open ref_cur2 for select F_USERNAME, F_USERCODE, F_USERID from Tb_System_User where F_userid = 1000; x := xmltype(ref_cur2); rowxml := x.extract('/ROWSET/ROW').getClobVal(0, 0); Dbms_Lob.append(mergeXml, rowxml); Dbms_Lob.writeappend(mergeXml, 9, '</ROWSET>'); Dbms_Output.put_line('=====合併後的信息====='); Dbms_Output.put_line(mergeXml); end;
執行這段代碼輸出的結果是這樣的htm
=====完整的REFCURSOR結構===== <?xml version="1.0"?> <ROWSET> <ROW> <F_USERNAME>系統管理員</F_USERNAME> <F_USERCODE>admin</F_USERCODE> <F_USERID>1</F_USERID> </ROW> </ROWSET> =====只提取行信息===== <ROW> <F_USERNAME>系統管理員</F_USERNAME> <F_USERCODE>admin</F_USERCODE> <F_USERID>1</F_USERID> </ROW> =====合併後的信息===== <ROWSET><ROW> <F_USERNAME>系統管理員</F_USERNAME> <F_USERCODE>admin</F_USERCODE> <F_USERID>1</F_USERID> </ROW> <ROW> <F_USERNAME>黃燕</F_USERNAME> <F_USERCODE>HUANGYAN</F_USERCODE> <F_USERID>1000</F_USERID> </ROW> </ROWSET>
從上邊打印的結果看,咱們已經成功的將兩個遊標 ref_cur
和ref_cur2
中咱們須要的列信息合併到了一個xml文檔中。那麼接下了,咱們就須要經過解析這個xml並返回一個新的sys_refcursor
,這裏你有必要了解如下oracle xmltable
的用法(https://docs.oracle.com/cd/B1...內存
Dbms_Output.put_line(mergeXml); open ref_cur3 for select * from xmltable('/ROWSET/ROW' Passing xmltype(mergeXml) Columns F_USERNAME varchar2(100) path 'F_USERNAME', F_USERCODE varchar2(100) path 'F_USERCODE');
簡單說明下xmltable
構造函數
/ROWSET/ROW
xml做爲早期數據傳輸,序列化和反序列化的文件格式,在oracle中也有良好的支持。因此,對於基於語言之上的知識,各個語言實現方式基本相識。基礎終究是重要的。