从 Plsql 中的光标获取 Clob 值

Posted

技术标签:

【中文标题】从 Plsql 中的光标获取 Clob 值【英文标题】:Get Clob Value From Cursor in Plsql 【发布时间】:2020-11-02 08:05:01 【问题描述】:

我想从我的光标中检索 clob 值,并附加每个循环数据。我试图达到像这样的 clob 值 R_SER_HIZ_MST."XMLTYPE".GETCLOBVAL() 命令,但是当我将它与 DBMS_LOB.APPEND(CLOBTORETURN,v_TEMPLOB);一起使用时,我收到数字或值错误。我是否做错了什么或如何获取 clob 值并附加另一个 clob 然后从函数返回此 clob(在本例中为 CLOBTORETURN)?

我的 Plsql 函数代码:

    CREATE OR REPLACE FUNCTION SOS_TABS.GET_CALL_LIST(    P_IK_KOD           IN VARCHAR2,
                                                          P_ORG_KOD      IN VARCHAR2,
                                                          P_SER_KOD      IN VARCHAR2)
      RETURN VARCHAR2
      IS
    
    
        CURSOR C_SER_HIZ_MST (vc_servis_org_kod VARCHAR2, vc_servis_ser_kod VARCHAR2, vc_ekodenekbel_param VARCHAR2) IS
            SELECT VALUE(table_temp) AS "XMLTYPE"
              FROM XMLTABLE ('/ROWSET/ROW' PASSING
              DBMS_XMLGEN.GETXMLTYPE('
                   SELECT *
              FROM SER_HIZ_MST "shm"
                INNER JOIN SER_SERVIS_TNM "sst1"
                  ON "shm".ORG_KOD = "sst1".ORG_KOD
                  AND "shm".SER_KOD = "sst1".SER_KOD
                INNER JOIN SER_BELGE_TIP_TNM "sbtt"
                  ON "shm".BELGE_KOD = "sbtt".BELGE_KOD
                INNER JOIN SER_SEHIR_TNM "sst"
                  ON "shm".ULKE_KOD = "sst".ULKE_KOD
                  AND "shm".SEHIR_KOD = "sst".SEHIR_KOD
                INNER JOIN SER_ILCE_TNM "sit"
                  ON "shm".ULKE_KOD = "sit".ULKE_KOD
                  AND "shm".SEHIR_KOD = "sit".SEHIR_KOD
                  AND "shm".ILCE_KOD = "sit".ILCE_KOD
                INNER JOIN SER_MUSTERI_TNM "smt"
                  ON "shm".MUS_ID = "smt".ID
              WHERE "sst1".ORG_KOD = (CASE WHEN ''' || vc_servis_org_kod || ''' IS NOT NULL THEN ''' || vc_servis_org_kod || ''' ELSE NULL END
                )
                AND "sst1".SER_KOD = (
                CASE WHEN ''' || vc_servis_ser_kod || ''' IS NOT NULL THEN ''' || vc_servis_ser_kod || ''' ELSE NULL END
                )
                AND "shm".IK_KOD = ''' || P_IK_KOD || '''
                AND "sbtt".BELGE_KOD = ''' || vc_ekodenekbel_param || '''
                AND "shm".DURUM = ''ACIK''
                ')
              ) table_temp;
    
       v_TEMPLOB CLOB;
       CLOBTORETURN CLOB;
    
    BEGIN

dbms_lob.CREATETEMPORARY(CLOBTORETURN,TRUE);--iniatialize clobtoreturn here
  dbms_lob.open(CLOBTORETURN, DBMS_LOB.LOB_READWRITE);
  dbms_lob.append(CLOBTORETURN, '"results":[');
    
    FOR R_SER_HIZ_MST IN C_SER_HIZ_MST(V_SERVIS_ORG_KOD, V_SERVIS_SER_KOD, V_EKODENEKBEL_PARAM)
        LOOP
    SELECT R_SER_HIZ_MST."XMLTYPE".GETCLOBVAL() INTO v_TEMPLOB FROM DUAL;
       DBMS_LOB.APPEND(CLOBTORETURN,v_TEMPLOB);
    
        END LOOP;
    
    RETURN CLOBTORETURN; 
    END;

我的环境:Oracle 11g 数据库

【问题讨论】:

【参考方案1】:

尝试直接在光标中选择getclobval,而无需将其从双重选择为临时clob。如果没有示例数据和结构,很难回答出了什么问题。

另一种选择是将LISTAGG 函数扩展为LOB 参数,例如in this post。这让我看起来更灵活。然后你可以用clob得到一行并将其导出到json数组。

原始代码呢,下面的代码为我成功完成(我排除了从双重选择):

QL> set echo on
SQL> 
SQL> create or replace function f_clobify( p_dummy varchar2)
  2  return clob
  3  is
  4    lv_ret_clob clob;
  5  begin
  6    dbms_lob.createtemporary(lv_ret_clob, true);
  7    dbms_lob.open(lv_ret_clob, dbms_lob.lob_readwrite);
  8    dbms_lob.append(lv_ret_clob, '"results":[');
  9  
 10    for r in (
 11      select VALUE(table_temp).getclobval() AS val
 12      FROM XMLTABLE (
 13        '/ROWSET/ROW'
 14        PASSING DBMS_XMLGEN.GETXMLTYPE(replace(q'[select '#val' as v from dual union select '#val_2' from dual]', '#val', p_dummy))
 15      ) table_temp
 16    ) loop
 17      dbms_lob.append(lv_ret_clob, r.val);
 18    end loop;
 19  
 20    dbms_lob.close(lv_ret_clob);
 21  
 22    return lv_ret_clob;
 23  end;
 24  /

Function F_CLOBIFY compiled

SQL> select f_clobify(dummy)
  2  from dual
  3  /

F_CLOBIFY(DUMMY)                                                                
--------------------------------------------------------------------------------
"results":[<ROW><V>X</V></ROW><ROW><V>X_2</V></ROW>

【讨论】:

以上是关于从 Plsql 中的光标获取 Clob 值的主要内容,如果未能解决你的问题,请参考以下文章

如何在oracle plsql中提取和打印函数外的光标值

通过直接 sql 的 plsql 光标

如何从光标中获取布尔值(Java SQLite)

如何通过光标获取android中的时间戳列值?

获取textarea文本框所选字符光标位置索引,以及选中的文本值;textarea高度自适应,随着内容增加高度增加;获取输入框中的光标位置

C# 和 PlSql 光标