在Oracle APEX中,我不能在CLOB中追加超过32kb的数据

时间:2019-03-22 12:41:47

标签: oracle plsql oracle-apex

我将文本存储在数据库表中,其中许多短行包含大约70-90个字符的长字段。 (出于历史原因)。我想将这些字段(行)附加到APEX(CKEditor)的CLOB中,并且在许多情况下确实超过了32k。 我已经尝试了很多方法,但是似乎有些局限。只要文本小于32k,我的代码就可以正常工作!我的计划是将其保存在新表中,并使用Clob代替。我有APEX 5.01。 超过32k时,出现“ ORA-06502:PL / SQL:数字或值错误”。

declare
  l_clob     CLOB;
  l_seq      number;
  cursor textrader_cur is
  SELECT F1NR,FHTTYP,RADNR,FHTEXT,DATUM,UPPTAGEN,NUSER FROM DATATXT WHERE  DATATXT.F1NR = :P10_F1NR ORDER BY F1NR,FHTTYP,RADNR;
  TYPE datatext_typ IS TABLE OF DATATXT%ROWTYPE INDEX BY PLS_INTEGER;
  l_datatext  datatext_typ;

begin
  l_clob := empty_clob();
  DBMS_LOB.CREATETEMPORARY(l_clob,true);

  apex_collection.create_or_truncate_collection(p_collection_name => 'TEXT');

  select count(1) into x from DATATXT@HUMANAUTV WHERE DATATXT.F1NR = :P10_F1NR;
  if x > 0 then
    open textrader_cur;
    loop
      fetch textrader_cur bulk collect into l_datatext LIMIT 200;
      for indx in 1..l_datatext.COUNT loop
        y := length(l_datatext(indx).fhtext);
        dbms_lob.writeappend (l_clob,y,l_datatext(indx).fhtext);
        --l_clob := l_clob || l_datatext(indx).fhtext; -- This causes same error
      end loop;
      EXIT WHEN l_datatext.COUNT = 0; 
    end loop;
    close textrader_cur;

    l_seq := apex_collection.add_member(p_collection_name => 'TEXT',
       p_d001            => sysdate,
       p_d002            => sysdate,
       p_n001            => dbms_lob.getlength(l_clob),
       p_clob001         => l_clob);  

    -- :P10_WP       := l_clob;
    SELECT clob001 into :P10_WP FROM APEX_COLLECTIONS WHERE SEQ_ID = l_seq     AND COLLECTION_NAME='TEXT';   
  end if;
end;

3 个答案:

答案 0 :(得分:1)

PL / SQL提供了一个dbms_lob包来操纵此数据类型。我在另一种技术(zope / python)中解决类似问题的方式是创建一个框架: 要从db读取,它以多行返回数据 要写入db,它将以多象素调用的形式发送数据,服务器最终将其合并。

您可以在这里Blob Journey from Database To Browser

答案 1 :(得分:0)

问题是代码的最后一行。会话状态变量(例如P10_WP)均为VARCHAR2,并且限制为32767个字符。您可以在调用它们的APEX函数中看到(example)。因此,您不能为PL / SQL页面项分配超过32k个字符

但是显然,您可以在HTML表单项中放置超过32k个字符!因此,这是一个尴尬的解决方法-您必须在不使用APEX页面项目的情况下将Clob数据传入和传出HTML表单项目。通常,这是通过将Clob写入Collection,然后使用AJAX调用Application Process来检索它来完成的,因为JavaScript的字符限制没有问题。

您似乎已经TEXT集合自己一个人了,但是您仍然必须编写自己的按需应用程序流程,以便可以将集合加载到JavaScript中,并且从那里将其放在HTML表单项中。如果您将内置的apex.ajax.clob功能与CLOB_CONTENT集合一起使用,将会更容易。

我浏览了一些有关此的文章,以及this one is pretty well written and straightforward

简短的版本是将代码中的集合名称更改为CLOB_CONTENT,然后将此JavaScript函数放在页面上并调用它。

function clob_get(){
        var clob_ob = new apex.ajax.clob(
            function(){
                var rs = p.readyState
                if(rs == 1||rs == 2||rs == 3){
                    $x_Show('AjaxLoading');
                }else if(rs == 4){
                    $s('P10_WP',p.responseText);
                    $x_Hide('AjaxLoading');
                }else{return false;}
            }
        );
        clob_ob._get();
    }

答案 2 :(得分:0)

APEX中的PL / SQL限制为32k,pl / sql将Clobs视为varchar,仅此而已。我的问题无法在APEX内解决