1. 程式人生 > >Oracle PL/SQL處理CLOB欄位的經驗

Oracle PL/SQL處理CLOB欄位的經驗

http://space.itpub.net/111631/viewspace-605827

這段時間在客戶現場處理SP處理模版內容替換的技術問題,如果是單點的處理,當然非常簡單,使用replace就可以解決問題,但是需要將關鍵TAG替換成動態行數呢?這就比較麻煩了,下面是處理過程的記錄

首先需要說明一下,其實這樣的功能使用程式來處理會非常簡單,但是處於對技術的追求,還是需要大膽的嘗試一下的,哈哈

先想到的就是使用funcation來進行處理,將內容輸入,替換後輸出多簡單,函式如下:
create or replace function Fun_GetTaFundnav_zj
   ---------------------------------------------------------------------------------------
    -- 版    權: 上海XXXXXXXXXXX有限公司
    -- 版    本:  XXX
    -- 開發人員: yeliang.wang
    -- 建立日期: 20090609
    -- 模組編號: 私有函式
    -- 模組名稱: XXXXXXX動態資料(郵件)
    -- 描    述:
    -- 輸入引數: 過濾前模板內容
    -- 輸出引數: 過濾後模板內容
    ---------------------------------------------------------------------------------------
    -- 修改作者:
    -- 修改日期:
    -- 修改內容:
    ---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
(
  --i_content   clob, --過濾前模板內容
  i_fundcode  varchar2, --產品編號
  i_tradedate varchar2  ---服務型別
)
return clob
as
  newClob    clob;
  srcClob    clob;
  v_content  VARCHAR2 (32767);

  vBuffer    VARCHAR2 (32767);
  l_amount   BINARY_INTEGER := 32767;
  l_pos      PLS_INTEGER := 1;
  l_clob_len PLS_INTEGER;

  --對XXXXXX進行定位
  cursor r_cust is select * from XX_XX  t1 where t1.XX = i_XXX and t1.XXX in ('0','9') and t1.date = i_date;
begin
    select DESCRIPTION into srcClob from products where productid = 1;

    v_content := '<TR>';
  --生成HTML程式碼--
    for r in r_cust loop
      v_content := v_content||'<TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
                            ||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||';</TD>'
                            ||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||';</TD>'
                            ||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||';</TD>'
                            ||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||';</TD>'
                            ||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||';</TD>';

    end loop;
    v_content := v_content||'</TR>';

    --模板轉換
    --v_result := replace(i_content,'${fund_replace}',v_content);
  return newClob;
end Fun_GetTaFundnav_zj;

執行結果:ORA-03127: 在活動操作結束之前不允許進行操作

暈。。難道是不能使用自定義函式對CLOB進行替換嗎?查了相關資料,也沒有最後的頭緒。。。突發奇想的把問題定位於FUNCTION本身,那麼就使用Procedure來處理吧,並且結合dbms_lob來對clob進行處理

儲存過程如下:

replaceClob_new --處理CLOB替換過程:
CREATE OR REPLACE PROCEDURE replaceClob_new (
srcClob IN CLOB,
replaceStr IN VARCHAR2,
replaceWith IN VARCHAR2,
newClob OUT CLOB
)
IS

vBuffer    VARCHAR2 (32767);
l_amount   BINARY_INTEGER := 32767;
l_pos      PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;


BEGIN
   newClob  := EMPTY_CLOB;
  -- initalize the new clob


 dbms_lob.createtemporary(newClob,TRUE);
 --newClob := EMPTY_CLOB;
 --srcClob := EMPTY_CLOB;
 l_clob_len := dbms_lob.getlength(srcClob);

 WHILE l_pos < l_clob_len
  LOOP
    dbms_lob.read(srcClob, l_amount, l_pos, vBuffer);

    IF vBuffer IS NOT NULL THEN
      -- replace the text
      vBuffer := replace(vBuffer, replaceStr, replaceWith);
      -- write it to the new clob
      dbms_lob.writeappend(newClob, LENGTH(vBuffer), vBuffer);
    END IF;
    l_pos := l_pos + l_amount;
  END LOOP;


EXCEPTION
  WHEN OTHERS THEN
    RAISE;
END;

PR_INSERT --先將自己造的測試資料插入:
create or replace procedure pr_insert
 is
 
begin

        insert into tmp_XXX_info1
         (
               ..相關欄位
           )
          select      seq_XXXX.nextval as id   ,
                      c.subject                      ,
                      1,
                      '

[email protected]'                        ,
                      c.CONTENT,
                      1,
                      1,
                      1      ,
                      1,
                      to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') ,
                      -1                     ,
                      '',
                      ''                     ,
                      1             ,
                      1              ,
                      '',
                      '',
                      '',
                      '',
                      ''
          from XXX c;
commit;
          PR_CLOB_TEST('373010','20090121');

end pr_insert;

PR_CLOB_TEST --將模版內容進行替換:
CREATE OR REPLACE PROCEDURE PR_CLOB_TEST
(
  i_fundcode  varchar2, --產品編號
  i_tradedate varchar2  ---服務型別
)
IS
LnewClob  CLOB := EMPTY_CLOB;
LsrcClob  CLOB := EMPTY_CLOB;
varC clob;
ln number(4);
vStrt number(4);
v_content clob;

CURSOR CURSOR_TEMP_CATAN IS
 select content from tmp_email_info1;
BEGIN
    vStrt := 5;
    -- initalize the new clob
    FOR r IN (select * from XXX t1 where t1.code = i_code and t1.status in ('0','9') and t1.date = i_date and rownum < 10)
    loop
        v_content := v_content||'<TR><TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
                              ||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||'</TD>'
                              ||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||'</TD>'
                              ||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||'</TD>'
                              ||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||'</TD>'
                              ||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||'</TD>'
                              ||'</TR>';
      end loop;
  
    OPEN CURSOR_TEMP_CATAN;
        LOOP
        FETCH CURSOR_TEMP_CATAN INTO
        LsrcClob;
        EXIT WHEN CURSOR_TEMP_CATAN%NOTFOUND;

        REPLACECLOB_NEW(LsrcClob,'&{fund_replace}',v_content,LnewClob);

        select content into varC from tmp_email_info1 for update;
      
        ln := Length(LnewClob);
        dbms_lob.write(varC, ln, vStrt, LnewClob);
      
        commit;
      
    END LOOP;

EXCEPTION
  WHEN OTHERS THEN
    RAISE;
END;

最終結果:測試成功

總結:整個過程就是將一個HTML模版進行關鍵字的HTML片段替換,是用來給資料閘道器傳送郵件用的,在開發的過程中間遇到了很多問題(在這裡不一一例舉了),由於PL/SQL在處理超長字元的時候會比較多的限制,用PL/SQL來對這樣的功能進行處理真的有點得不償失,嗨。。。但是最終還是完成了,哈哈。。記錄下相關操作和部分程式碼大家參考

相關推薦

Oracle PL/SQL處理CLOB經驗

http://space.itpub.net/111631/viewspace-605827 這段時間在客戶現場處理SP處理模版內容替換的技術問題,如果是單點的處理,當然非常簡單,使用replace就可以解決問題,但是需要將關鍵TAG替換成動態行數呢?這就比較麻煩了,下面是處

Oracle處理Clob 轉換請求無法實現或不合理

處理clob(使用java.io.Reader)的時候出現,ORA-01460: 轉換請求無法實現或不合理從oracle 9i R2匯出程式到oracle 10G R2版本,作業系統是從Hp UX到RED HAT LINUX X64版本,剛開始以為是字符集的問題,我以為是量的

oracle建立檢視包含clob,報錯:資料型別不一致:應為-,但卻獲得CLOB

在oracle中建立檢視的時候,語句中包含有clob型別的欄位。檢視建立語句大概如下: CREATE OR REPLACE FORCE VIEW "T_PROJECTS" ("ID", "NAME","DSC_INFO") AS ( select a.id,a.name,

sql 處理資料為空 如果為空轉換成別的值

判斷欄位是否為空,如果為空轉成你要的字元 1.oracle : nvl(“欄位名”,’轉換後的值’);//欄位名是雙引號,轉換後的值是單引號 2.sql Server: isnull(“欄位名”

PL/SQL 查詢的顯示不全

最近在工作當中遇到了一個問題。 Oracle資料庫,PL/SQL developer。 問題描述:SQL語句在PL/SQL中執行,查詢結果當中的一些欄位顯示結果不全。效果如下圖: 欄位A的值不符合要求。顯示出來的值是正確結果的一部分。 也有網友遇到類似的問題,但是都沒有找

Oracle中如何查詢CLOB型別的內容

語法 select * from table_name where dbms_lob.instr(欄位名(clod型別),'查詢條件',1,1) > 0; 具體例項 /*查詢質押單據資訊*/ SELECT * FROM EDI.MID_LOG_OPEN_PLATF

Oracle中BLOB和CLOB的操作

一、區別和定義        LONG: 可變長的字串資料,最長2G,LONG具有VARCHAR2列的特性,可以儲存長文字一個表中最多一個LONG列  LONG RAW: 可變長二進位制資料,最長2G  CLOB: 字元大物件Clob 用來儲存單位元組的字元資料  NCLOB

在64Win7下安裝Oracle 10g客戶端,以及PL/SQL Developer、TOAD的經驗

用了整整兩天時間才在64位Win7下裝好了Oracle的開發環境(包括Oracle的客戶端和第三方客戶端工具),這樣的效率真是太讓人汗顏了。不過好在最後還是安裝成功了。 安裝過程: 1、下載Oracle 10g的客戶端程式,檔名是 10201_client_win32.zip,下載地址

工作總結15 sql的insert語句插入大量字串到oracleclob

    當通過insert語句直接插入大量字串(主要是html的內容),超過4000字元時候,就會報:ORA-01489: 字串連線的結果過長.    雖然欄位是clob,足以儲存,但是通過這種直接插

Oracle varchar2改成大型別clob

做專案中經常碰到資料庫改欄位問題,給自己做個記錄,下次直接可以拿來用了。Oracle 有些欄位直接修改會報錯ORA-22858: invalid alteration of datatype。不允許修改。不允許修改怎麼辦呢。。總不能把表幹掉重新建欄位吧。這在生產肯定行不通。可以先建個新欄

ORACLE PL/SQL Developer連線本地Oracle 11g 64資料庫

PL/SQL Developer連線本地Oracle 11g 64位資料庫 1.登入PL/SQL Developer 這裡省略Oracle資料庫和PL/SQL Developer的安裝步驟,注意在安裝PL/SQL Developer軟體時,不要安裝在Program Files (x86)目錄下,不然

關於TP3.2框架讀取Sql server中文資料以及處理亂碼的一些小心得

最近要做一個專案,需要使用TP3.2框架,之前什麼也不會,就硬著頭皮上了,結果真的鬧了挺多emmmmmm挺低階的錯誤,就像SQL Server中文欄位的讀取,一開始我是照著讀取英文欄位的格式來寫的,在Model層裡 public function getAdminByUsername($userna

查詢Oracle中帶有Clob的表的大小

在oracle裡面,由於lob欄位有獨立的lob segment來儲存,所以查詢需要DBA_SEGMENTS S, DBA_INDEXES  2張表結合才可查出結果。 以下是實驗SQL說明: 表名:GJ_NORM_POOL 表歸屬使用者名稱:ORACLE

oracle中使用sql查詢時為空則賦值預設

oracle 通過 nvl( )函式sql 查詢時為 空值 賦預設值 oracle 函式介紹之nvl   函式宣告:nvl(col,val)   說明:當col為空時取val作為返回值,當col不為空時取col值。   用處:最主要的是格式化資料,比如計算金額時,不想出現

Oracle中的BLOB和CLOB

一般為了更好的管理ORACLE資料庫,通常像圖片、檔案、音樂等資訊就用BLOB欄位來儲存,先將檔案轉為二進位制再儲存進去。而像文件或者是較長的文字,就用CLOB儲存,這樣對以後的查詢更新儲存等操作都提供很大的方便。 1.BLOB  BLOB全稱為二進位制大型物件(Binary Larg

Oracle+Mybatis批量插入含有Sequence和CLOB

參考 當oracle+mybaits批量insert遇到CLOB型別欄位,通過使用 begin .. end 將語句放入Oracle 的塊裡實現批量提交。常規的,帶有 Sequence 的插入語句需要使用到 Mybatis 的 selectKey 標籤。但是,帶有 Sequence 和

Oracle資料庫中clob轉成MD5碼,並能在where條件或者group中使用

轉載自:https://blog.csdn.net/siyouzi/article/details/29589613   1.建立java source ------------Java source------------------------ create or repl

Java更新OracleCLOB的值

Java用JDBC操作Oracle的CLOB欄位也是算最近遇到的一個知識點,也算是基礎,在此記錄一篇。因為CLOB型別的特殊性,並不能通過for update進行操作,那麼就需要java將要修改的值通過流寫入到clob中。那麼更新CLOB之前需要先清空CLOB的值update xxxx.data_interf

kettle能抽取oracleclob麼?

學習使用kettle,在學習的過程中遇到一些連線資料庫的問題,經過一番努力之後,終於找到解決方案,現將遇到的問題和解決方案公佈如下,有不對的地方請大家指正。  問題一:用spoon設計了一個轉換,主要功能是從資料檔案中讀取記錄,然後直接存入資料庫(我們使用的是IBM D

Oracle CLOB為查詢條件, 模糊查詢/精確查詢

Linux系統有時候需要測試某個埠的連通性,使用者可以參考如下方法來測試。 方法一、telnet法  telnet為使用者提供了在本地計算機上完成遠端主機工作的能力,因此可以通過telnet來測試埠的連通性,具體用法格式: telnet ip port 說明