oracle 合併多個sys_refcursor

来源:https://www.cnblogs.com/yfrs/archive/2018/05/28/mergecursor.html
-Advertisement-
Play Games

一、背景 在數據開發中,有時你需要合併兩個動態游標sys_refcursor。 開發一個存儲過程PROC_A,這個過程業務邏輯相當複雜,代碼篇幅較長。一段時間後要開發一個PROC_B,要用PROC_A同樣的邏輯,而且在這個過程中,還要迴圈調用PROC_A這個過程。擺在你面前的有兩個選擇。 打開PL/ ...


一、背景

在數據開發中,有時你需要合併兩個動態游標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

二、思路

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

  1. 序列化sys_refcursor為xml文檔,ORACLE對xml支持還不錯,12C已經有JSON格式了
  2. 使用ORACLE xml解析的方法,對序列化的xml文檔,添加、刪除、修改
  3. 轉換為記憶體表,通過游標返回查詢的結果

為此你需要掌握的知識有

三、實現

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

1 <?xml version="1.0"?>
2 <ROWSET>
3 <ROW>
4 <COLUMNNAME1></COLUMNNAME1>
5 <COLUMNNAME2></COLUMNNAME2>
6 <...>...</...>
7 </ROW>
8 ....
9 </ROWSET>

 

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

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

 1 Declare
 2 x xmltype;
 3 rowxml clob;
 4 mergeXml clob;
 5 ref_cur Sys_Refcursor;
 6 ref_cur2 Sys_Refcursor;
 7 ref_cur3 Sys_Refcursor;
 8 begin
 9   open ref_cur for
10    select F_USERNAME, F_USERCODE, F_USERID
11    from Tb_System_User
12    where F_userid = 1;
13  Dbms_Lob.createtemporary(mergeXml, true);
14  Dbms_Lob.writeappend(mergeXml, 8, '<ROWSET>');
15  x := xmltype(ref_cur);
16  Dbms_Output.put_line('=====完整的REFCURSOR結構=====');
17  Dbms_Output.put_line(x.getClobVal());
18  Dbms_Output.put_line('=====只提取行信息=====');
19  rowxml := x.extract('/ROWSET/ROW').getClobVal(0, 0);
20  Dbms_Output.put_line(rowxml);
21  Dbms_Lob.append(mergeXml, rowxml);ROWSET
22  open ref_cur2 for
23   select F_USERNAME, F_USERCODE, F_USERID
24   from Tb_System_User
25   where F_userid = 1000;
26  x := xmltype(ref_cur2);
27  rowxml := x.extract('/ROWSET/ROW').getClobVal(0, 0);
28  Dbms_Lob.append(mergeXml, rowxml);
29  Dbms_Lob.writeappend(mergeXml, 9, '</ROWSET>');
30  Dbms_Output.put_line('=====合併後的信息=====');
31  Dbms_Output.put_line(mergeXml);
32 end;

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

 1 =====完整的REFCURSOR結構=====
 2 <?xml version="1.0"?>
 3 <ROWSET>
 4 <ROW>
 5 <F_USERNAME>系統管理員</F_USERNAME>
 6 <F_USERCODE>admin</F_USERCODE>
 7 <F_USERID>1</F_USERID>
 8 </ROW>
 9 </ROWSET>
10 
11 =====只提取行信息=====
12 <ROW>
13 <F_USERNAME>系統管理員</F_USERNAME>
14 <F_USERCODE>admin</F_USERCODE>
15 <F_USERID>1</F_USERID>
16 </ROW>
17 
18 =====合併後的信息=====
19 <ROWSET><ROW>
20 <F_USERNAME>系統管理員</F_USERNAME>
21 <F_USERCODE>admin</F_USERCODE>
22 <F_USERID>1</F_USERID>
23 </ROW>
24 <ROW>
25 <F_USERNAME>黃燕</F_USERNAME>
26 <F_USERCODE>HUANGYAN</F_USERCODE>
27 <F_USERID>1000</F_USERID>
28 </ROW>
29 </ROWSET>

   從上邊列印的結果看,我們已經成功的將兩個游標 ref_curref_cur2中我們需要的列信息合併到了一個xml文檔中。那麼接下了,我們就需要通過解析這個xml並返回一個新的sys_refcursor,這裡你有必要瞭解以下oracle xmltable的用法(https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions228.htm)接上邊代碼

1 Dbms_Output.put_line(mergeXml);
2 open ref_cur3 for
3   select *
4   from xmltable('/ROWSET/ROW' Passing xmltype(mergeXml) Columns
5         F_USERNAME varchar2(100) path 'F_USERNAME',
6         F_USERCODE varchar2(100) path 'F_USERCODE'); 

簡單說明下xmltable構造函數

  • 聲明xpath,指明你需要解析的dom在哪裡,比如從根找到ROW /ROWSET/ROW
  • 指明你要查詢的xmltype
  • 定義轉換列,比如把ROW下邊的F_USERNAME這個節點值,映射到游標列F_USERNAME 這個列中

四、總結

xml作為早期數據傳輸,序列化和反序列化的文件格式,在oracle中也有良好的支持。所以,對於基於語言之上的知識,各個語言實現方式基本相識。基礎終究是重要的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 承自上一篇中的函數圖形,有人問,能不能別把畫個圖搞那麼複雜,我說當然,只要你有一臺mac。 話說出來很瀟灑的樣子,充斥著一股迷之自信。 可能這就是mac用戶典型的特征,儘管也許並沒有那麼值得驕傲。 其實在上一篇中我見到照片的時候就看出來用的是什麼軟體了,mac內置的grapher。grapher的誕 ...
  • Linux DNS原理簡介及配置 DNS簡介 DNS原理 功能變數名稱解析的過程 資源記錄 DNS BIND安裝配置 一、簡介 一般來講功能變數名稱比IP地址更加的有含義、也更容易記住,所以通常用戶更習慣輸入功能變數名稱來訪問網路中的資源,但是電腦主機在互聯網中只能通過IP識別對方主機,那麼就需要DNS功能變數名稱解析服務了。 ...
  • 首先展示錯誤信息: win10更新系統後,之前連接的伺服器都連接不上了,應該用一下方法解決: 運行 gpedit.msc,打開本地組策略:電腦配置>管理模板>系統>憑據分配>加密Oracle修正,選擇啟用,選擇易受攻擊。 ...
  • 安裝截圖軟體 1.下載安裝python-xlib apt-get install python-xlib 2.下載截圖軟體包 wget http://packages.linuxdeepin.com/deepin/pool/main/d/deepin-scrot/deepin-scrot_2.0-0 ...
  • Flashloader程式主要是用來將你的Application下載進i.MXRT支持的所有外部非易失性存儲器中,為後續從外部存儲器啟動做準備。BootROM只有啟動Application功能,沒有下載更新Application功能,而Flashloader最核心的就是下載更新Application... ...
  • 環境 centos:7.2 JDK:1.8 Flume:1.8 一、Flume 安裝 1) 下載 wget http://mirrors.tuna.tsinghua.edu.cn/apache/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz 2) 解壓 tar – ...
  • 誤刪除了部分重要數據,已提交,需要恢復。首先嘗試flashback query閃回數據。資料庫運行在歸檔模式,首先確認資料庫的SCN的變化:SQL> col fscn for 999999999999999999999SQL> col nscn for 999999999999999999999SQ ...
  • url=jdbc:oracle:thin:@localhost:1521:orcldriver=oracle.jdbc.OracleDriverusrname=GJQ (PLSQL Developer 登錄時候的用戶名 即通過cmd命令創建的用戶)password=gjq (PLSQL Develo ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...