Oracle 11g行欄位拼接WMSYS.WM_CONCAT問題Not A LOB

来源:https://www.cnblogs.com/Albertiy/archive/2018/08/27/9543217.html
-Advertisement-
Play Games

Oracle 11g行欄位拼接WMSYS.WM_CONCAT問題Not A LOB 一、問題出現 項目中的某個查詢需要將表中某個欄位不重覆地拼接起來,百度得到該函數 ,以及 函數,前者只能使用逗號' '連接,後者可以定製連接符。 但由於listagg不能直接在參數中使用 去重,因此採用 函數。 SQ ...


Oracle 11g行欄位拼接WMSYS.WM_CONCAT問題Not A LOB

一、問題出現

項目中的某個查詢需要將表中某個欄位不重覆地拼接起來,百度得到該函數WMSYS.WM_CONCAT(欄位),以及listagg(欄位,連接符)函數,前者只能使用逗號','連接,後者可以定製連接符。

但由於listagg不能直接在參數中使用distinct去重,因此採用WM_CONCAT函數。

SQL格式如下:

select t.id, t.pjname
   from (select A.id as id, count(distinct B.name) as countname,
                to_char(wmsys.wm_concat(distinct to_char(B.name))) as pjname
           from A left join B  on A.id = B.id
          where 1 = 1
          group by A.id) t
  where t.countname > 1;

這段SQL的作用是,以A表的id為組,不重覆的拼接B表的name,並統計name去重後的個數,最後返回name去重後仍多於1個的id和拼接name。

開發時這段SQL是正常的,然而,這段SQL在測試庫上卻會報錯ORA-22922: 不存在的 LOB 值

二、原因分析

經網上查資料,發現問題出在WMSYS.WM_CONCAT函數在Oracle不同版本中的返回值類型不同。

該項目開發使用的是Oracle 11.2.0.1.0,而測試與現場使用的均為Oracle 11.2.0.4.0,項目開始時的疏忽導致開發與測試的不一致。

將拼接函數外的to_char去掉後,SQL不會報錯,但對象不是String類型(可能是java.sql.Clob類型),無法直接toString獲得。

同時,在PLSQL Developer 9.0中直接運行SQL時,該拼接結果直接顯示為<CLOB>,可在select結果中使用to_char()函數,而該函數在項目dal層直接運行仍報錯。

三、問題解決

  1. 去掉WM_CONCAT函數外的to_char()
select t.id, t.pjname
  from (select A.id as id, count(distinct B.name) as countname,
               wmsys.wm_concat(distinct to_char(B.name)) as pjname
          from A left join B on A.id = B.id
         where 1 = 1
         group by A.id) t
 where t.countname > 1;
  1. 將LOB類型對象轉換為String類型,有兩種方法:在SQL中使用Oracle函數,或者在後端dal層轉換,參考網上的文章,我選擇後者,因為完整的SQL要實現的功能本身比較複雜,要儘量簡化在資料庫中的操作。
  • 獲取結果集中的欄位並判斷
    String array1 = "";
    try {
        array = array[1].getClass().toString().equals("class java.lang.String") ? array[1].toString() : ClobToString((Clob) array[1]);
    } catch (SQLException e) {
        array14 = array[1].toString();
    } catch (IOException e) {
        e.printStackTrace();
    }
    public String ClobToString(Clob clob) throws SQLException, IOException {
        String reString = "";
        Reader is = clob.getCharacterStream();
        BufferedReader br = new BufferedReader(is);
        String s = br.readLine();
        StringBuffer sb = new StringBuffer();
        while (s != null) {
            sb.append(s);
            s = br.readLine();
        }
        reString = sb.toString();
        if(br!=null){
            br.close();
        }
        if(is!=null){
            is.close();
        }
        return reString;
    }

問題解決。還是得看看listagg方法的用法,畢竟官方相容性強些,但覺得listagg不如WM_CONCAT簡單易用。

三、補充

listagg(列名,'分隔符')除了要多嵌套一層子查詢,其實也挺方便的,它是從11g起才出現的聚合函數,要實現去重和統計,需要使用distinct的多列去重。

select A.id, t.countname, t.pjname
  from A
  left join (SELECT id,count(name) as countname,
                    LISTAGG(to_char(name), ',') WITHIN GROUP(ORDER BY name) AS pjname
               FROM (select distinct B.id as id, B.name as name
                       from B
                       left join C
                         on B.name = C.name
                      where C.gender = 'female')
              where 1 = 1
              group by id) t
    on A.id = t.id
 where countname is null or countname <= 1;

四、參考文章


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

-Advertisement-
Play Games
更多相關文章
  • 1、打開terminal(終端) 2、open .bash_profile (打開.bash_profile文件,如果文件不存在就 創建文件:touch .bash_profile 編輯文件:open -e bash_profile) 3、直接更改彈出的.bash_profile文件內容 4、com ...
  • ubuntu18.04:配置/etc/network/interfaces已無用,需修改/etc/netplan/50-cloud-init.yaml ...
  • ORA_DBA:是ORACLE 的特有用戶,是超級管理員許可權,建成DBA 它具有管理資料庫的最高許可權。 註明:需要以管理員身份運行cmd,不然第4步會失敗(點開始,輸入cmd,右鍵以管理員身份運行) 1.利用命令查看當前系統用戶:net user 這是當前系統中所有的用戶。 2.查看用戶組 net ...
  • 索引 1、概述 MySQL索引的建立對於MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。 建立索引會占用磁碟 ...
  • 主要區別: 1).MyISAM是非事務安全型的,而InnoDB是事務安全型的。 2).MyISAM鎖的粒度是表級,而InnoDB支持行級鎖定。 3).MyISAM支持全文類型索引,而InnoDB不支持全文索引。 4).MyISAM相對簡單,所以在效率上要優於InnoDB,小型應用可以考慮使用MyIS ...
  • InnoDB:支持事務處理等不加鎖讀取支持外鍵支持行鎖不支持FULLTEXT類型的索引不保存表的具體行數,掃描表來計算有多少行DELETE 表時,是一行一行的刪除InnoDB 把數據和索引存放在表空間裡面跨平臺可直接拷貝使用InnoDB中必須包含AUTO_INCREMENT類型欄位的索引表格很難被壓 ...
  • 一. 指定路徑 在上一篇里,二進位包解壓後,全部放入在/usr/local/mysql目錄下,在安裝時指定了基礎目錄和數據目錄, --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data 。 Linux是建議第三方軟體放在/opt下。官網文 ...
  • Preface Oracle claimed that 11g RAC is supported on Redhat Linux 7 and above version,but there're still some incompatible issues in inplementing 11g G ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...