【问题标题】:In Oracle APEX I cannot append data more than 32kb in CLOB在 Oracle APEX 中,我不能在 CLOB 中附加超过 32kb 的数据
【发布时间】:2019-03-22 12:41:47
【问题描述】:

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

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;

【问题讨论】:

    标签: oracle plsql oracle-apex


    【解决方案1】:

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

    但显然你可以在一个 HTML 表单项中放置超过 32k 个字符!所以这是一个尴尬的解决方法 - 您必须在不使用 APEX 页面项的情况下将 clob 数据输入和输出 HTML 表单项。通常这是通过将 clob 写入 Collection,然后使用 AJAX 调用应用程序进程来检索它来完成的,因为 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();
        }
    

    【讨论】:

    • 不,它不在最后一行,:P10_WP 是一个富文本编辑器 (clob)。如果我对 :P10_WP 的分配发表评论,我仍然会遇到同样的错误。如果我在 'db,s_lob.writeappend' 上加上注释,则没有错误。如果我限制循环,那么将有
    • 我认为您的 JavaScript 示例还可以,但问题是从数据库表中填充我的 clob,而不是分配表单项
    【解决方案2】:

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

    你可以在这里看到Blob Journey from Database To Browser

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2021-08-14
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-28
        • 1970-01-01
        • 2018-12-11
        相关资源
        最近更新 更多