久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

oracle合并多個sys

169次閱讀
沒有評論

共計 3456 個字符,預計需要花費 9 分鐘才能閱讀完成。

自動寫代碼機器人,免費開通

這篇文章給大家分享的是有關 oracle 合并多個 sys_refcursor 的案例的內容。丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,一起跟隨丸趣 TV 小編過來看看吧。

一、背景

在數據開發中,有時你需要合并兩個動態游標 sys_refcursor。

開發一個存儲過程 PROC_A, 這個過程業務邏輯相當復雜,代碼篇幅較長。一段時間后要開發一個 PROC_B, 要用 PROC_A 同樣的邏輯, 而且在這個過程中,還要循環調用 PROC_A 這個過程。擺在你面前的有兩個選擇。

打開 PL/SQL, 仔細的讀 PROC_A 這個過程,一直到明白了所有的邏輯,然后在自己的過程中重寫這個邏輯。

直接復制 PROC_A 這個過的代碼過來,多寫極端。還是業界標準大法好

針對循環調用的,建立一個臨時表,循環插入數據到臨時表(但這里還有一個問題,每次返回的游標可能列都不相同,建立臨時表就顯得復雜了)

好吧,這個新的過程是完成了,可是看上去,它更復雜了,代碼量更大了。完全不能接受,必須改改!
這時,已經默默打開了 ORACLE 官方幫助文檔 https://docs.oracle.com/cd/B19306_01/index.htm,尋找一個可行的辦法,最終目標標是要解析,整合,合并 游標 sys_refcursor

二、思路

經過搜索查詢,找到以下可行的方案

序列化 sys_refcursor 為 xml 文檔,ORACLE 對 xml 支持還不錯,12C 已經有 JSON 格式了

使用 ORACLE xml 解析的方法,對序列化的 xml 文檔,添加、刪除、修改

轉換為內存表,通過游標返回查詢的結果

為此你需要掌握的知識有

使用 Dbms_Lob 個 package 操作 clob 類型數據,因為解析后的游標可能用 varchar2 是裝不下的,幫助地址 https://docs.oracle.com/cd/E11882_01/timesten.112/e21645/d_lob.htm#TTPLP600。

重點掌握 Oracle 類型 xmltype 如何使用 https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/t_xml.htm#BABHCHHJ

三、實現

從上邊的幫助文檔中,知道 xmltype 的構造函數中可以直接傳入游標 xmltype(refcursor)從而得到一個 xmltype,調用 xmltype 的 getClobVal 方法,可得到序列化的結果,所以它的結構是這樣的

?xml version= 1.0 ? 
 ROWSET 
 ROW 
 COLUMNNAME1 /COLUMNNAME1 
 COLUMNNAME2 /COLUMNNAME2 
 ... ... /... 
 /ROW 
 /ROWSET

所以,如果需要合并兩個數據列相同游標,只需要提取 DOM 中的 ROW 節點數據保存到定義的 clob 字段中去。

提取 dom 中片段,采用標準的 xpath 語法,/ROWSET/ROW 這里提取 ROW 信息

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;

  執行這段代碼輸出的結果是這樣的

===== 完整的 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/B19306_01/server.102/b14200/functions228.htm) 接上邊代碼

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 構造函數

聲明 xpath,指明你需要解析的 dom 在哪里,比如從根找到 ROW /ROWSET/ROW

指明你要查詢的 xmltype

定義轉換列,比如把 ROW 下邊的 F_USERNAME 這個節點值,映射到游標列 F_USERNAME 這個列中

附:sys_refcursor 和 cursor 優缺點比較

優點比較

優點一:sys_refcursor,可以在存儲過程中作為參數返回一個 table 格式的結構集(我把他認為是 table 類型,容易理解,其實是一個游標集),cursor 只能用在存儲過程,函數,包等的實現體中,不能做參數使用。

優點二:sys_refcursor 這東西可以使用在包中做參數,進行數據庫面向對象開放。哈哈。我喜歡。cursor 就不能。

缺點比較:

缺點:sys_refcursor 不能用 open,close,fetch 進行操作。不好學,難理解。

cursor 可以用 open,close,fetch 操作,容易學,易懂

感謝各位的閱讀!關于“oracle 合并多個 sys_refcursor 的案例”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向 AI 問一下細節

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-12-04發表,共計3456字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 那曲县| 平远县| 镇宁| 廊坊市| 平武县| 霍林郭勒市| 秭归县| 洛宁县| 茶陵县| 武夷山市| 乌拉特中旗| 酒泉市| 新竹市| 密山市| 武定县| 太仓市| 三台县| 阿合奇县| 钟祥市| 雷州市| 高邑县| 诸暨市| 威海市| 江油市| 遂溪县| 吴堡县| 望都县| 宁都县| 汕头市| 岚皋县| 九龙坡区| 仁寿县| 大竹县| 韶关市| 南平市| 垣曲县| 温宿县| 郓城县| 大石桥市| 称多县| 临澧县|