В Oracle APEX я не могу добавить данные размером более 32 КБ в CLOB - PullRequest
1 голос
/ 22 марта 2019

У меня есть текст, хранящийся в таблице базы данных, много коротких строк длиной около 70-90 символов.(по историческим причинам).Я хочу добавить эти поля (строки) в CLOB в APEX (CKEditor), и он во многих случаях превышает 32k.Я пытался во многих отношениях, но это, кажется, какой-то предел.Мой код работает нормально, если текст меньше 32 КБ!Мой план - сохранить его в новой таблице и использовать вместо него clob.У меня есть APEX 5.01.Я получаю «ORA-06502: PL / SQL: ошибка с числовым значением или значением», когда оно превышает 32 000.

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 ]

1 голос
/ 22 марта 2019

PL / SQL предоставляет пакет dbms_lob для манипулирования этим типом данных.Для решения аналогичной проблемы в другой технологии (zope / python), которую я рассмотрел, было создание фреймворка: для чтения из базы данных он возвращал данные в виде многострочных строк..

Вы можете видеть это здесь Путешествие BLOB-объектов из базы данных в браузер

0 голосов
/ 22 марта 2019

PL / SQL в APEX ограничены 32k, pl / sql обрабатывает clobs как varchar и все.Моя проблема не может быть решена в течение APEX

0 голосов
/ 22 марта 2019

Проблема в последней строке вашего кода. Все переменные состояния сеанса (например, P10_WP) имеют размер VARCHAR2 и ограничены 32767 символами. Вы можете видеть это в вызывающих их функциях APEX ( пример ). Таким образом, вы не можете назначить более 32 тыс. Символов для элемента страницы PL / SQL .

Но очевидно, что вы можете поместить более 32 тыс. Символов в элемент формы HTML! Так что это неловкий обходной путь - вы должны получать данные clob внутри и вне элемента формы HTML без использования элементов страницы APEX. Обычно это делается путем записи clob в коллекцию, а затем с помощью AJAX-вызовов к процессу приложения для его получения, поскольку у JavaScript нет проблем с ограничениями символов.

Похоже, что вы частично продвинулись в этом с вашей коллекцией TEXT, но вам все равно придется написать свой собственный процесс приложения по требованию, чтобы вы могли загрузить коллекцию в JavaScript и поместить ее в элементе формы HTML оттуда. Будет проще, если вы используете встроенную функциональность apex.ajax.clob с коллекцией CLOB_CONTENT.

Я просмотрел несколько статей об этом, и эта довольно хорошо написана и проста .

Краткая версия - изменить название вашей коллекции в вашем коде на 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();
    }
...